Gradle, "sourceCompatibility" vs "targetCompatibility"?

130

Was ist die Beziehung / der Unterschied zwischen sourceCompatibilityund targetCompatibility? Was passiert, wenn sie auf unterschiedliche Werte eingestellt sind?

Laut Gradle-Dokumentation :

sourceCompatibilityist "Java-Versionskompatibilität beim Kompilieren der Java-Quelle". targetCompatibilityist "Java-Version zum Generieren von Klassen für."

Meines Wissens nach targetCompatibilitywird Java-Bytecode generiert, der mit einer bestimmten Java-Version kompatibel ist. Ist dies eine Teilmenge der Funktionalität von sourceCompatibility?

Mike Rylander
quelle

Antworten:

80

targetCompatibilityund sourceCompatibilityKarten zu -target releaseund -source releasein Javac. Quelle ist im Grunde die Ebene der Ausgangssprache und Ziel ist die Ebene des generierten Bytecodes.

Weitere Details finden Sie im Abschnitt javac the cross compilation .

Matt
quelle
1
Der obige Link verweist auf doc für Java 7. Ich frage mich, ob Sie so etwas wie docs.oracle.com/en/java/javase/11/tools/… möchten .
Brian Agnew
62

Seien Sie vorsichtig, wenn Sie diese verwenden; Wir wurden von Leuten gebissen, die Annahmen machten.

Nur weil Sie sourceCompability (oder targetCompatibility) von 1.5 verwenden, heißt das nicht, dass Sie Ihren Code immer mit JDK 1.6 kompilieren können und erwarten, dass er unter JDK 1.5 funktioniert. Das Problem sind die verfügbaren Bibliotheken.

Wenn Ihr Code zufällig eine Methode aufruft, die nur in JDK 1.6 verfügbar ist, wird er weiterhin mit den verschiedenen Kompatibilitätsoptionen für die Ziel-VM kompiliert. Wenn Sie es ausführen, schlägt es jedoch fehl, da die fehlerhafte Methode nicht vorhanden ist (Sie erhalten eine MethodNotFoundException oder ClassNotFoundException).

Aus diesem Grund vergleiche ich die Kompatibilitätseinstellung immer mit der tatsächlichen Java-Version, unter der ich baue. Wenn sie nicht übereinstimmen, kann ich den Build nicht bestehen.

user1644873
quelle
4
Dies ist eine subtile, aber sehr wichtige Beobachtung.
Natix
Wie vergleichst du sie?
zero01alpha
Warum scheitern Sie am Build? Die Option "Bootstrap-Klassenpfad" dient nur zur Minderung dieses Problems. Sie können immer den richtigen Bootstrap verwenden und es sollte gut funktionieren.
Codebender
6
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())So behebe ich dieses Problem direkt am Anfang der Datei build.gradle.
Xerus
2
Seit Java 9 gibt es jetzt eine neue javacOption --release, mit der dieses Problem behoben werden soll, indem nur die Verwendung der in der angegebenen Java-Version verfügbaren API zugelassen wird. Weitere Informationen
James Mudd
35

sourceCompatibility = gibt an, dass die Version der Java-Programmiersprache zum Kompilieren von Java- Dateien verwendet wird. Beispiel: sourceCompatibility 1.6 = gibt an, dass Version 1.6 der Java-Programmiersprache zum Kompilieren von Java- Dateien verwendet wird.

Standardmäßig ist sourceCompatibility = "Version der aktuell verwendeten JVM" und targetCompatibility = sourceCompatibility

targetCompatibility = Die Option stellt sicher, dass die generierten Klassendateien mit den von targetCompatibility angegebenen VMs kompatibel sind. Beachten Sie, dass in den meisten Fällen der Wert der Option -target der Wert der Option -source ist. In diesem Fall können Sie die Option -target weglassen.

Klassendateien werden auf dem von targetCompatibility angegebenen Ziel und in späteren Versionen ausgeführt, jedoch nicht in früheren Versionen der VM

Ein Jakhar
quelle
Wie finden wir heraus, welche in unserem Projekt verwendet werden?
isJulian00
0

Meiner Meinung nach bedeutet "sourceCompatibility", welche Funktion Sie in Ihrem Quellcode verwenden können. Wenn Sie beispielsweise sourceCompatibility auf 1.7 setzen, können Sie keinen Lambda-Ausdruck verwenden, der eine neue Funktion in Java 8 ist, obwohl Sie eine JDK-Version haben 1.8.
Was "targetCompatibility" betrifft, bedeutet dies, auf welcher Version von jre die generierte Klassendatei ausgeführt werden kann. Wenn Sie sie auf 1.8 setzen, wird sie möglicherweise nicht erfolgreich auf jdk 1.7 ausgeführt, aber normalerweise auf einer höheren Version von jdk.

Haoyu Wang
quelle
0

Dies sind die Flags für den Befehl javac.

javac [options] [sourcefiles]

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

Mit anderen Worten: Sie schreiben einen Code in eine sourceVersion und kompilieren Ihre Klassen auf die targetVM-Version. Um es zB auf einer anderen Workstation mit älterer Java-Version auszuführen.

Laut: https://docs.oracle.com/de/java/javase/11/tools/javac.html

Benjamin
quelle