Gradle, "sourceCompatibility" vs "targetCompatibility"?

130

Qual é a relação / diferença entre sourceCompatibilitye targetCompatibility? O que acontece quando eles são definidos com valores diferentes?

De acordo com a documentação da Gradle :

sourceCompatibilityé "Compatibilidade da versão Java a ser usada ao compilar a origem Java". targetCompatibilityé "versão Java para a qual gerar classes".

Meu entendimento é que targetCompatibilityirá gerar bytecode java que é compatível com uma versão específica do Java, este é um subconjunto da funcionalidade de sourceCompatibility?

Mike Rylander
fonte

Respostas:

80

targetCompatibilitye sourceCompatibilitymapas para -target releasee -source releaseem javac. A origem é basicamente o nível do idioma de origem e o destino é o nível do bytecode gerado.

Mais detalhes podem ser encontrados na seção compilação cruzada javac .

Matt
fonte
1
O link acima está apontando para doc para Java 7. Gostaria de saber se você deseja algo como docs.oracle.com/en/java/javase/11/tools/… ?
Brian Agnew
63

Tenha cuidado ao usá-los; fomos mordidos por pessoas que fazem suposições.

Só porque você usa sourceCompability (ou targetCompatibility) de 1.5 não significa que você sempre pode compilar seu código com o JDK 1.6 e esperar que ele funcione no JDK 1.5. O problema são as bibliotecas disponíveis.

Se o seu código chamar algum método disponível apenas no JDK 1.6, ele ainda será compilado com as várias opções de compatibilidade para a VM de destino. Mas quando você executá-lo, ele falhará porque o método incorreto não está presente (você receberá um MethodNotFoundException ou ClassNotFoundException).

Por esse motivo, eu sempre comparo a configuração de Compatibilidade com a versão Java real em que estou construindo. Se eles não corresponderem, falho na compilação.

user1644873
fonte
4
Esta é uma observação sutil, mas muito importante.
Natix #
Como você os compara?
Zero01alpha 20/09/16
Por que você falha na construção? A opção "caminho de classe de autoinicialização" é fornecida apenas para atenuar esse problema. Você sempre pode usar o bootstrap adequado e deve funcionar perfeitamente.
Codebender
6
if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current())É assim que eu resolvo esse problema, logo no início do arquivo build.gradle.
Xerus
2
Desde o Java 9, agora existe uma nova javacopção --releasedestinada a solucionar esse problema, permitindo apenas o uso da API disponível na versão Java especificada. Para saber mais sobre este see stackoverflow.com/a/43103038/4653517
James Mudd
35

sourceCompatibility = especifica que a versão da linguagem de programação Java seja usada para compilar arquivos .java . por exemplo, sourceCompatibility 1.6 = especifica que a versão 1.6 da linguagem de programação Java seja usada para compilar .java arquivos .

Por padrão sourceCompatibility = "versão da JVM atual em uso" e targetCompatibility = sourceCompatibility

targetCompatibility = A opção garante que os arquivos de classe gerados sejam compatíveis com as VMs especificadas por targetCompatibility. Observe que, na maioria dos casos, o valor da opção -target é o valor da opção -source; nesse caso, você pode omitir a opção -target.

Os arquivos de classe serão executados no destino especificado por targetCompatibility e em versões posteriores, mas não nas versões anteriores da VM

A Jakhar
fonte
como descobrimos quais o nosso projeto está usando?
isJulian00
0

Na minha opinião, "sourceCompatibility" significa o recurso que você pode usar em seu código-fonte. Por exemplo, se você definir sourceCompatibility como 1.7, não poderá usar a expressão lambda, que é um novo recurso no java 8, mesmo que a versão jdk seja 1.8
Quanto a “targetCompatibility”, significa em qual versão do jre o arquivo de classe gerado pode ser executado; se você o definir como 1.8, poderá não ser executado com êxito no jdk 1.7, mas geralmente poderá ser executado na versão superior do jdk.

haoyu wang
fonte
0

Estes são os sinalizadores para o comando javac.

javac [options] [sourcefiles]

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

Em outras palavras: você escreve um código em uma sourceversão e compila suas classes na targetversão da VM. Para executá-lo, por exemplo, em outra estação de trabalho com a versão java mais antiga.

De acordo com: https://docs.oracle.com/en/java/javase/11/tools/javac.html

Benjamin
fonte