tabla son sistema que programas programacion operativo maquina los interprete encargados ejemplos cualquier cual corran compilados compilador codigo java jvm compatibility java-7 java-8

programacion - son los encargados de que los programas compilados en java corran en cualquier sistema operativo



¿Se puede compilar el código Java 8 para ejecutar en Java 7 JVM? (5)

Los métodos predeterminados requieren tales cambios en el bytecode y la JVM que hubieran sido imposibles de hacer en Java 7. El verificador de bytecode de Java 7 y siguientes rechazará interfaces con cuerpos de método (a excepción del método de inicializador estático). Intentar emular los métodos predeterminados con métodos estáticos del lado de la persona que llama no produciría los mismos resultados, porque los métodos predeterminados se pueden anular en las subclases. Retrolambda tiene soporte limitado para backporting métodos predeterminados, pero nunca puede ser totalmente backported porque realmente requiere nuevas características de JVM.

Lambdas podría correr en Java 7 tal como está, si las clases API necesarias simplemente existirían allí. La instrucción invocada dinámica existe en Java 7, pero hubiera sido posible implementar lambdas para que genere las clases lambda en tiempo de compilación (las versiones anteriores de JDK 8 lo hicieron de esa manera) en cuyo caso funcionaría en cualquier versión de Java. (Oracle decidió utilizar invokedynamic para lambdas para futuras pruebas, tal vez un día JVM tendrá funciones de primera clase, por lo que invookedynamic se puede cambiar para usarlas en lugar de generar una clase para cada lambda, mejorando así el rendimiento.) Lo que Retrolambda hace es que procesa todas las instrucciones dinámicas invocadas y las reemplaza con clases anónimas; lo mismo que hace Java 8 en tiempo de ejecución cuando se llama a lamdba invookedynamic la primera vez.

Repetir anotaciones es solo azúcar sintáctico. Son bytecode compatibles con versiones anteriores. En Java 7 solo necesita implementarse los métodos de ayuda (por ejemplo, getAnnotationsByType ) que ocultan los detalles de implementación de una anotación de contenedor que contiene las anotaciones repetidas.

AFAIK, las anotaciones de tipo solo existen en tiempo de compilación, por lo que no deberían requerir cambios de bytecode, por lo que basta con cambiar el número de versión de byte de las clases compiladas de Java 8 para que funcionen en Java 7.

Los nombres de parámetros de métodos existen en el bytecode con Java 7, por lo que también es compatible. Puede obtener acceso a ellos leyendo el bytecode del método y mirando los nombres de las variables locales en la información de depuración del método. Por ejemplo, Spring Framework hace exactamente eso para implementar @PathVariable , por lo que probablemente haya un método de biblioteca al que pueda llamar. Debido a que los métodos de interfaz abstractos no tienen un cuerpo de método, esa información de depuración no existe para los métodos de interfaz en Java 7, y AFAIK tampoco en Java 8.

Las otras características nuevas son en su mayoría nuevas API, mejoras en HotSpot y herramientas. Algunas de las nuevas API están disponibles como bibliotecas de terceros (por ejemplo, ThreeTen-Backport y streamsupport ).

Summa summarum, los métodos predeterminados requieren nuevas funciones de JVM, pero las demás funciones de idioma no. Si desea usarlos, tendrá que compilar el código en Java 8 y luego transformar el bytecode con Retrolambda en el formato Java Retrolambda . Como mínimo, se debe cambiar la versión del bytecode y javac no permite -source 1.8 -target 1.7 por lo que se requiere un retrotraslador.

Java 8 introduce características importantes del nuevo idioma, como expresiones lambda.

¿Están estos cambios en el lenguaje acompañados por cambios tan significativos en el bytecode compilado que impedirían que se ejecutara en una máquina virtual Java 7 sin usar algún retrotraductor?


Por lo que sé, ninguno de estos cambios en JDK 8 requirió la adición de nuevos códigos de bytes. Parte de la instrumentación lambda se está realizando utilizando invokeDynamic (que ya existe en JDK 7). Entonces, desde el punto de vista del conjunto de instrucciones JVM, nada debería hacer que la base de código sea incompatible. Sin embargo, hay una gran cantidad de API asociadas y mejoras en el compilador que podrían hacer que el código de JDK 8 sea difícil de compilar / ejecutar bajo JDK anteriores (pero no lo he intentado).

Tal vez el siguiente material de referencia puede ayudar de alguna manera a enriquecer la comprensión de cómo se están instrumentando los cambios relacionados con lambda.

Estos explican en detalle cómo se instrumentan las cosas bajo el capó. Quizás puedas encontrar la respuesta a tus preguntas allí.


Puedes hacer -source 1.7 -target 1.7 luego compilará. Pero no compilará si tiene características específicas de java 8 como lambdas


Si está dispuesto a usar un "retrotraslador", pruebe la excelente Retrolambda de Esko Luontola: Retrolambda


No, el uso de las características 1.8 en su código fuente requiere que se oriente a 1.8 VM. Acabo de probar la nueva versión de Java 8 e intenté compilar con -target 1.7 -source 1.8 , y el compilador se rehusa:

$ javac Test -source 1.8 -target 1.7 javac: source release 1.8 requires target release 1.8