Java 9 javac
ma nową flagę --release
:
> javac --help
...
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9
Czym się różni od flag -source
i -target
? Czy to tylko skrót -source X -target X
?
Java 9 javac
ma nową flagę --release
:
> javac --help
...
--release <release>
Compile for a specific VM version. Supported targets: 6, 7, 8, 9
Czym się różni od flag -source
i -target
? Czy to tylko skrót -source X -target X
?
Odpowiedzi:
Nie dokładnie.
JEP 247: Kompiluj dla starszych wersji platform definiuje tę nową opcję wiersza polecenia--release
:
Zdefiniowaliśmy nową opcję wiersza poleceń
--release
, która automatycznie konfiguruje kompilator do tworzenia plików klas, które będą powiązane z implementacją danej wersji platformy. Dla platformy predefiniowanychjavac
,--release N
jest równoważna-source N -target N -bootclasspath <bootclasspath-from-N>
. (podkreślenie moje)
Więc nie, to nie jest równoważne -source N -target N
. Powód tego dodania jest podany w sekcji „Motywacja”:
javac
udostępnia dwie opcje wiersza poleceń-source
i-target
, których można użyć do wybrania wersji języka Java akceptowanej przez kompilator oraz wersji plików klas, które tworzy. Jednak domyślniejavac
kompiluje się z najnowszą wersją interfejsów API platformy. Skompilowany program może więc przypadkowo wykorzystać API dostępne tylko w aktualnej wersji platformy. Takie programy nie mogą działać na starszych wersjach platformy, niezależnie od wartości przekazanych do-source
i-target
. opcje. Jest to długoterminowy problem związany z użytecznością, ponieważ użytkownicy oczekują, że korzystając z tych opcji, otrzymają pliki klas, które można uruchomić na określonej wersji platformy.
Krótko mówiąc, określenie opcji źródłowej i docelowej nie jest wystarczające do kompilacji krzyżowej. Ponieważ javac
domyślnie kompilują się z najnowszymi interfejsami API platformy, nie można zagwarantować, że będą działać na starszych wersjach. Musisz także określić -bootclasspath
opcję odpowiadającą starszej wersji, aby poprawnie skompilować krzyżowo. Obejmuje to poprawną wersję interfejsu API do kompilacji i umożliwiającą wykonanie na starszej wersji. Ponieważ bardzo często o tym zapomniano, zdecydowano się dodać jedną opcję wiersza poleceń, która zrobiła wszystko, co niezbędne do poprawnej kompilacji krzyżowej.
Dalsze czytanie na liście mailingowej i Oracle Docs . Oryginalny błąd został zgłoszony tutaj . Należy zauważyć, że od czasu integracji tej opcji, kompilacje JDK są dostarczane w pakiecie z opisami interfejsów API platformy starszych wydań, wymienionymi w sekcji „Ryzyka i założenia”. Oznacza to, że nie potrzebujesz starszej wersji zainstalowanej na komputerze, aby kompilacja krzyżowa działała.
--release
flagi, byłaby wywnioskowana z JDK używanego do kompilacji, który zasadniczo różni się od JDK, którego docelowo używasz -source
i -target
. Może cię to ugryźć, jeśli zdarzy ci się używać klas / metod wprowadzonych nigdy w JDK, a nie w tym, na który celujesz. Jest to bardzo subtelne w przypadku, gdy kompilator wybierze przeciążenie metody, które zostało dodane w późniejszej wersji zamiast tego z poprzedniej, którą zamierzałeś, w ten sposób dyskretnie łamiąc zgodność binarną.
--release X
to coś więcej niż tylko skrót do -source X -target X
ponieważ -source
i -target
nie są wystarczające do bezpiecznej kompilacji do starszej wersji. Musisz także ustawić -bootclasspath
flagę, która musi odpowiadać starszemu wydaniu (o czym często się zapomina). Tak więc, w Javie 9 zrobili jedną --release
flagę, która zastępuje trzy flagi: -source
, -target
i -bootclasspath
.
Oto przykład kompilacji do Java 1.7:
javac --release 7 <source files>
Pamiętaj, że nie musisz nawet instalować JDK 7 na swoim komputerze. JDK 9 zawiera już potrzebne informacje, aby zapobiec przypadkowemu połączeniu z symbolami, które nie istniały w JDK 7.