I metodi predefiniti richiedono tali modifiche al bytecode e alla JVM che sarebbero stati impossibili da eseguire su Java 7. Il verificatore bytecode di Java 7 e versioni precedenti rifiuterà le interfacce con i corpi del metodo (ad eccezione del metodo di inizializzazione statica). Cercare di emulare metodi predefiniti con metodi statici sul lato chiamante non produrrebbe gli stessi risultati, poiché i metodi predefiniti possono essere sovrascritti in sottoclassi. Retrolambda ha un supporto limitato per i metodi predefiniti di backport, ma non può mai essere completamente backport perché richiede veramente nuove funzionalità JVM.
Lambdas potrebbe funzionare su Java 7 così com'è, se le classi API necessarie esistessero proprio lì. L'istruzione invokedynamic esiste su Java 7, ma sarebbe stato possibile implementare lambdas in modo da generare le classi lambda in fase di compilazione (le prime build JDK 8 lo facevano in quel modo) nel qual caso avrebbe funzionato su qualsiasi versione Java. (Oracle ha deciso di utilizzare invokedynamic per lambdas per future prove; forse un giorno JVM avrà funzioni di prima classe, quindi quindi invokedynamic può essere modificato per usarle invece di generare una classe per ogni lambda, migliorando così le prestazioni.) Retrolambda fa che elabora tutte quelle istruzioni invocate e le sostituisce con classi anonime; lo stesso di quello che fa Java 8 in fase di esecuzione quando una chiamata invocata dinamica lamdba viene chiamata per la prima volta.
La ripetizione delle annotazioni è solo zucchero sintattico. Sono compatibili bytecode con le versioni precedenti. In Java 7 dovresti solo implementare te stesso i metodi di supporto (ad esempio getAnnotationsByType ) che nascondono i dettagli di implementazione di un'annotazione contenitore che contiene le annotazioni ripetute.
AFAIK, le Annotazioni di tipo esistono solo al momento della compilazione, quindi non dovrebbero richiedere modifiche al bytecode, quindi basta cambiare il numero di versione del bytecode delle classi compilate Java 8 per farle funzionare su Java 7.
I nomi dei parametri del metodo esistono nel bytecode con Java 7, quindi anche questo è compatibile. È possibile accedervi leggendo il bytecode del metodo e osservando i nomi delle variabili locali nelle informazioni di debug del metodo. Ad esempio Spring Framework fa esattamente questo per implementare @PathVariable , quindi esiste probabilmente un metodo di libreria che potresti chiamare. Poiché i metodi di interfaccia astratti non hanno un corpo di metodo, tali informazioni di debug non esistono per i metodi di interfaccia in Java 7 e AFAIK né su Java 8.
Le altre nuove funzionalità sono principalmente nuove API, miglioramenti a HotSpot e strumenti. Alcune delle nuove API sono disponibili come librerie di terze parti (ad esempio ThreeTen-Backport e streamsupport ).
Summa summarum, i metodi predefiniti richiedono nuove funzionalità JVM ma le altre funzionalità linguistiche no. Se si desidera utilizzarli, è necessario compilare il codice in Java 8 e quindi trasformare il bytecode con Retrolambda in formato Java 5/6/7. Almeno la versione del bytecode deve essere cambiata e javac non consente -source 1.8 -target 1.7
quindi un retrotranslator.