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.
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.
Odpowiedzi:
Nie dokładnie.
JEP 247: Kompiluj dla starszych wersji platform definiuje tę nową opcję wiersza polecenia
--release
:Więc nie, to nie jest równoważne
-source N -target N
. Powód tego dodania jest podany w sekcji „Motywacja”: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.
źródło
--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.
źródło