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 versiones posteriores rechazará las interfaces con los cuerpos de los métodos (excepto el método de inicializador estático). Intentar emular métodos predeterminados con métodos estáticos en el lado de la persona que llama no produciría los mismos resultados, porque los métodos predeterminados pueden anularse en subclases. Retrolambda tiene un soporte limitado para los métodos predeterminados de backport, pero nunca puede ser completamente backport porque realmente requiere nuevas características de JVM.
Lambdas podría ejecutarse en Java 7 tal cual, si las clases de API necesarias simplemente existieran allí. La instrucción invocada dinámica existe en Java 7, pero habría sido posible implementar lambdas para que genere las clases lambda en tiempo de compilación (las primeras compilaciones de JDK 8 lo hicieron de esa manera) en cuyo caso funcionaría en cualquier versión de Java. (Oracle decidió usar invocados dinámicos para lambdas para pruebas futuras; tal vez algún día JVM tendrá funciones de primera clase, por lo que puede invocarse dinámico para usarlos en lugar de generar una clase para cada lambda, mejorando así el rendimiento). Lo que hace Retrolambda es que procesa todas esas instrucciones dinámicas invocadas y las reemplaza con clases anónimas; lo mismo que hace Java 8 en tiempo de ejecución cuando una lamdba invocada dinámicamente se llama por primera vez.
Repetir anotaciones es solo azúcar sintáctico. Son bytecode compatibles con versiones anteriores. En Java 7 solo necesitaría implementar 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 el momento de la compilación, por lo que no deberían requerir cambios de bytecode, por lo que solo cambiar el número de versión de bytecode de las clases compiladas de Java 8 debería ser suficiente para que funcionen en Java 7.
Los nombres de los parámetros del método existen en el bytecode con Java 7, por lo que también es compatible. Puede obtener acceso a ellos leyendo el código de bytes 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 podría 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 API nuevas, mejoras en HotSpot y herramientas. Algunas de las nuevas API están disponibles como bibliotecas de terceros (p. Ej. ThreeTen-Backport y streamsupport ).
En resumen, los métodos predeterminados requieren nuevas funciones de JVM, pero las otras funciones del lenguaje no. Si desea usarlos, deberá compilar el código en Java 8 y luego transformar el bytecode con Retrolambda al formato Java 5/6/7 . Como mínimo, la versión de bytecode debe cambiarse, y javac no -source 1.8 -target 1.7
lo permite, por lo que se requiere un retrotranslator.