¿Cuál es la diferencia entre “sourceCompatibility” y “targetCompatibility”?

5 minutos de lectura

Avatar de usuario de Mike Rylander
mike rylander

¿Cuál es la relación/diferencia entre sourceCompatibility y targetCompatibility? ¿Qué sucede cuando se establecen en valores diferentes?

De acuerdo con la Cadena de herramientas y compatibilidad sección de la Complemento Java Gradle documentación:

  • sourceCompatibility es “Compatibilidad con la versión de Java para usar al compilar el código fuente de Java”.
  • targetCompatibility es “Versión de Java para generar clases”.

Mi entendimiento es que targetCompatibility generará bytecode de Java que es compatible con una versión específica de Java. ¿Es este un subconjunto de la funcionalidad de sourceCompatibility?

Avatar de usuario de Matt
Mate

targetCompatibility y sourceCompatibility mapas a -target release y -source release en java. El origen es básicamente el nivel del idioma de origen y el destino es el nivel del código de bytes que se genera.

Se pueden encontrar más detalles en el Opciones de compilación cruzada para javac Sección de Referencia de herramientas para Java 8, para java 11, para java 17o para java 19.

avatar de usuario de user1644873
usuario1644873

Tenga cuidado cuando use estos; hemos sido mordidos por personas que hacen suposiciones.

El hecho de que use sourceCompability (o targetCompatibility) de 1.5 no significa que siempre pueda compilar su código con JDK 1.6 y esperar que funcione con JDK 1.5. El problema son las bibliotecas disponibles.

Si su código llama a algún método que solo está disponible en JDK 1.6, aún se compilará con las diversas opciones de compatibilidad para la máquina virtual de destino. Pero cuando lo ejecute, fallará porque el método infractor no está presente (obtendrá una excepción MethodNotFoundException o ClassNotFoundException).

Por esta razón, yo siempre compare la configuración de Compatibilidad con la versión real de Java bajo la que estoy construyendo. Si no coinciden, fallo la compilación.

  • Esta es una observación sutil, pero muy importante.

    – Natix

    08/04/2016 a las 13:23


  • ¿Cómo los comparas?

    – segundo desayuno

    20/09/2016 a las 18:00

  • ¿Por qué fallas en la compilación? La opción “classpath de arranque” se ofrece solo para mitigar este problema. Siempre puede usar el arranque adecuado y debería funcionar bien.

    – Codebender

    9 noviembre 2016 a las 15:30

  • if(JavaVersion.current() != JavaVersion.VERSION_1_8) throw new GradleException("This project requires Java 8, but it's running on "+JavaVersion.current()) Así es como soluciono este problema, justo al comienzo del archivo build.gradle.

    – xeruf

    6 de noviembre de 2017 a las 10:28

  • Desde Java 9 ahora hay una nueva javac opción --release destinado a abordar este problema, al permitir solo el uso de la API disponible en la versión de Java especificada. Para obtener más información sobre esto, consulte stackoverflow.com/a/43103038/4653517

    –James Mudd

    29 de marzo de 2019 a las 9:05

fuenteCompatibilidad = especifica que se utilizará la versión del lenguaje de programación Java para compilar .Java archivos por ejemplo, sourceCompatibility 1.6 = especifica que se use la versión 1.6 del lenguaje de programación Java para compilar .Java archivos

De forma predeterminada, sourceCompatibility = “versión de la JVM actual en uso” y targetCompatibility = sourceCompatibility

Compatibilidad de destino = La opción garantiza que los archivos de clase generados serán compatibles con las máquinas virtuales especificadas por targetCompatibility . Tenga en cuenta que, en la mayoría de los casos, el valor de la opción -target es el valor de la opción -source; en ese caso, puede omitir la opción -target.

Los archivos de clase se ejecutarán en el destino especificado por targetCompatibility y en versiones posteriores, pero no en versiones anteriores de la máquina virtual.

  • ¿Cómo averiguamos cuáles está usando nuestro proyecto?

    – esJulian00

    15 de junio de 2019 a las 19:49

Se han dado muchas buenas explicaciones de lo que sourceCompatibility contra targetCompatibility es bueno para y se puede encontrar otro buen artículo aquí Gradle: compatibilidad de origen frente a compatibilidad de destino. pero en lugar de sourceCompatibility contra targetCompatibility Yo sugeriría usar el Gradle toolchain (ver Cadenas de herramientas para proyectos JVM) que hace release o sourceCompatibility ajusta obsoletos y garantiza que las funciones de idioma (sourceCompatibility), código de bytes (targetCompatibility) y Java-API/-Bibliotecas (release) coincidirá con la versión de Java. (El único inconveniente es que el soporte IDE aún no está completamente establecido, pero está en camino).

En mi opinión, “sourceCompatibility” significa qué característica puede usar en su código fuente. Por ejemplo, si establece sourceCompatibility en 1.7, entonces no puede usar la expresión lambda, que es una característica nueva en Java 8, aunque su versión jdk es 1.8.
En cuanto a “targetCompatibility”, significa en qué versión de jre se puede ejecutar el archivo de clase generado, si lo configura en 1.8, es posible que no se ejecute correctamente en jdk 1.7, pero generalmente se puede ejecutar en una versión superior de jdk.

  • Esto realmente explica lo que se relaciona con el desarrollo en detalle.

    – Víctor Choy

    7 de septiembre de 2022 a las 3:13

Avatar de usuario de Benjamin
Benjamín

Estas son las banderas para el 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.
...

En otras palabras: escribes un código en un source versión y compilar sus clases a la target Versión de máquina virtual. Para ejecutarlo, por ejemplo, en otra estación de trabajo con una versión anterior de Java.

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

  • Esto realmente explica lo que se relaciona con el desarrollo en detalle.

    – Víctor Choy

    7 de septiembre de 2022 a las 3:13

¿Ha sido útil esta solución?