Gradle, „sourceCompatibility” czy „targetCompatibility”?


130

Jaki jest związek / różnica między sourceCompatibilityi targetCompatibility? Co się dzieje, gdy mają różne wartości?

Według dokumentacji Gradle :

sourceCompatibilityto „Zgodność wersji Java do użycia podczas kompilowania źródła Java”. targetCompatibilityto „Wersja Java do generowania klas”.

Rozumiem, że targetCompatibilitywygeneruje kod bajtowy Java zgodny z określoną wersją języka Java. Czy jest to podzbiór funkcji sourceCompatibility?

Odpowiedzi:


80

targetCompatibilityoraz sourceCompatibilitymapy do -target releasei -source releasew javac. Źródło to zasadniczo poziom języka źródłowego, a cel to poziom generowanego kodu bajtowego.

Więcej szczegółów można znaleźć w sekcji kompilacji javac .


1
Powyższe łącze wskazuje na dokumentację dotyczącą języka Java 7. Zastanawiam się, czy potrzebujesz czegoś takiego jak docs.oracle.com/en/java/javase/11/tools/… ?
Brian Agnew

62

Zachowaj ostrożność, kiedy ich używasz; zostaliśmy ugryzieni przez ludzi, którzy robili przypuszczenia.

To, że używasz sourceCompability (lub targetCompatibility) w wersji 1.5, nie oznacza, że ​​zawsze możesz skompilować swój kod za pomocą JDK 1.6 i oczekiwać, że będzie działał pod JDK 1.5. Problemem są dostępne biblioteki.

Jeśli zdarzy się, że Twój kod wywoła jakąś metodę, która jest dostępna tylko w JDK 1.6, nadal będzie kompilować się z różnymi opcjami zgodności dla docelowej maszyny wirtualnej. Ale kiedy go uruchomisz, zakończy się niepowodzeniem, ponieważ nie ma metody powodującej naruszenie (otrzymasz MethodNotFoundException lub ClassNotFoundException).

Z tego powodu zawsze porównuję ustawienie zgodności z rzeczywistą wersją Java, w której tworzę. Jeśli nie pasują, zawiodę kompilację.


4
To subtelna, ale bardzo ważna obserwacja.
Natix

Jak je porównujesz?
zero01alpha

Dlaczego zawodzisz kompilację? Opcja „bootstrap classpath” jest podana tylko w celu złagodzenia tego problemu. Zawsze możesz użyć odpowiedniego bootstrapa i powinno działać dobrze.
Codebender

6
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())W ten sposób rozwiązuję ten problem na samym początku pliku build.gradle.
Xerus

2
Od wersji Java 9 dostępna jest teraz nowa javacopcja --releasemająca na celu rozwiązanie tego problemu, zezwalając jedynie na korzystanie z API dostępnego w określonej wersji Java. Więcej na ten temat można znaleźć na stronie stackoverflow.com/a/43103038/4653517
James Mudd

35

sourceCompatibility = określa, która wersja języka programowania Java będzie używana do kompilowania plików .java . np. sourceCompatibility 1.6 = określa, że ​​do kompilacji ma być używana wersja 1.6 języka programowania Java plików .java .

Domyślnie sourceCompatibility = "wersja aktualnie używanej maszyny JVM" i targetCompatibility = sourceCompatibility

targetCompatibility = Ta opcja zapewnia, że ​​wygenerowane pliki klas będą zgodne z maszynami wirtualnymi określonymi przez targetCompatibility. Zauważ, że w większości przypadków wartością opcji -target jest wartość opcji -source; w takim przypadku możesz pominąć opcję -target.

Pliki klas będą działać w miejscu docelowym określonym przez targetCompatibility i na nowszych wersjach, ale nie we wcześniejszych wersjach maszyny wirtualnej


jak dowiedzieć się, które z nich są używane w naszym projekcie?
Julian00

0

Moim zdaniem „sourceCompatibility” oznacza, jakiej funkcji można użyć w kodzie źródłowym. Na przykład, jeśli ustawisz sourceCompatibility na 1.7, nie możesz użyć wyrażenia lambda, które jest nową funkcją w java 8, nawet jeśli wersja jdk to 1.8.
Jeśli chodzi o „targetCompatibility”, oznacza to, na której wersji jre można uruchomić wygenerowany plik klasy. Jeśli ustawisz ją na 1.8, może nie działać poprawnie na jdk 1.7, ale zwykle może działać na wyższej wersji jdk.


0

To są flagi polecenia javac.

javac [options] [sourcefiles]

Options:
...
-source release - Specifies the version of source code accepted.
...
-target release - Generates class files for a specific VM version.
...

Innymi słowy: piszesz kod w sourcewersji i kompilujesz swoje klasy do targetwersji VM. Aby go uruchomić np. Na innej stacji roboczej ze starszą wersją java.

Według: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.