Co to jest flaga --release w kompilatorze Java 9?

Odpowiedzi:

106

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 predefiniowanych javac, --release Njest 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”:

javacudostępnia dwie opcje wiersza poleceń -sourcei -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ślnie javackompiluje 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 -sourcei -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ż javacdomyś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ć -bootclasspathopcję 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.

Andrew Li
źródło
jedna wątpliwość, czy byłoby możliwe użycie funkcji z jdk 9-11 w kodzie i nadal działałoby na java runtime 8?
Cristiano,
Nie, nie byłoby ich w pliku binarnym jre 8
Rogue
Co wy mężczyźni przez „Platform API”? Czy coś jest na poziomie kodu bajtowego? lub coś związanego z podstawową platformą x86 lub interfejsami API systemu operacyjnego?
Jose Cifuentes
2
@JoseCifuentes, "Platform API" jest tutaj podane JDK API, którego wersja, bez --releaseflagi, byłaby wywnioskowana z JDK używanego do kompilacji, który zasadniczo różni się od JDK, którego docelowo używasz -sourcei -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ą.
Oliver Gondža
30

--release Xto coś więcej niż tylko skrót do -source X -target Xponieważ -sourcei -targetnie są wystarczające do bezpiecznej kompilacji do starszej wersji. Musisz także ustawić -bootclasspathflagę, która musi odpowiadać starszemu wydaniu (o czym często się zapomina). Tak więc, w Javie 9 zrobili jedną --releaseflagę, która zastępuje trzy flagi: -source, -targeti -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.

ZhekaKozlov
źródło