Standardmethoden erfordern solche Änderungen am Bytecode und an der JVM, die unter Java 7 nicht möglich gewesen wären. Der Bytecode-Verifizierer von Java 7 und niedriger lehnt Schnittstellen mit Methodenkörpern ab (mit Ausnahme der statischen Initialisierungsmethode). Der Versuch, Standardmethoden mit statischen Methoden auf der Aufruferseite zu emulieren, führt nicht zu denselben Ergebnissen, da Standardmethoden in Unterklassen überschrieben werden können. Retrolambda bietet nur eingeschränkte Unterstützung für das Backportieren von Standardmethoden, kann jedoch niemals vollständig zurückportiert werden, da wirklich neue JVM-Funktionen erforderlich sind.
Lambdas könnte unter Java 7 unverändert ausgeführt werden, wenn die erforderlichen API-Klassen nur dort vorhanden wären. Die aufgerufene dynamische Anweisung existiert unter Java 7, aber es wäre möglich gewesen, Lambdas so zu implementieren, dass sie die Lambda-Klassen zur Kompilierungszeit generiert (frühe JDK 8-Builds haben dies so gemacht). In diesem Fall würde sie auf jeder Java-Version funktionieren. (Oracle hat beschlossen, invokedynamic für Lambdas für die Zukunftssicherung zu verwenden. Vielleicht wird JVM eines Tages über erstklassige Funktionen verfügen, sodass invokedynamic geändert werden kann, um sie zu verwenden, anstatt für jedes Lambda eine Klasse zu generieren, wodurch die Leistung verbessert wird.) Retrolambda verbessert dies dass es alle diese aufgerufenen dynamischen Anweisungen verarbeitet und durch anonyme Klassen ersetzt; Das gleiche wie Java 8 zur Laufzeit, wenn eine Lamdba-Aufrufdynamik zum ersten Mal aufgerufen wird.
Das Wiederholen von Anmerkungen ist nur syntaktischer Zucker. Sie sind mit früheren Versionen Bytecode-kompatibel. In Java 7 müssten Sie nur die Hilfsmethoden (z. B. getAnnotationsByType ) selbst implementieren, die die Implementierungsdetails einer Container-Annotation verbergen, die die wiederholten Annotationen enthält.
AFAIK, Typanmerkungen sind nur zur Kompilierungszeit vorhanden, daher sollten keine Bytecode-Änderungen erforderlich sein. Daher sollte es ausreichen, nur die Bytecode-Versionsnummer der Java 8-kompilierten Klassen zu ändern, damit sie unter Java 7 funktionieren.
Methodenparameternamen sind im Bytecode mit Java 7 vorhanden, daher ist dies auch kompatibel. Sie können auf sie zugreifen, indem Sie den Bytecode der Methode lesen und die lokalen Variablennamen in den Debug-Informationen der Methode anzeigen. Zum Beispiel macht das Spring Framework genau das, um @PathVariable zu implementieren , also gibt es wahrscheinlich eine Bibliotheksmethode, die Sie aufrufen könnten. Da abstrakte Schnittstellenmethoden keinen Methodenkörper haben, sind diese Debug-Informationen für Schnittstellenmethoden in Java 7 und AFAIK auch nicht in Java 8 vorhanden.
Die anderen neuen Funktionen sind hauptsächlich neue APIs, Verbesserungen an HotSpot und Tools. Einige der neuen APIs sind als Bibliotheken von Drittanbietern verfügbar (z. B. ThreeTen-Backport und Streamsupport ).
Zusammenfassend lässt sich sagen, dass Standardmethoden neue JVM-Funktionen erfordern, die anderen Sprachfunktionen jedoch nicht. Wenn Sie sie verwenden möchten, müssen Sie den Code in Java 8 kompilieren und dann den Bytecode mit Retrolambda in das Java 5/ 6/ 7-Format umwandeln. Zumindest muss die Bytecode-Version geändert werden, und Javac lässt dies nicht zu, -source 1.8 -target 1.7
sodass ein Retrotranslator erforderlich ist.