Методы по умолчанию требуют таких изменений в байт-коде и JVM, которые было бы невозможно сделать в Java 7. Верификатор байт-кода в Java 7 и ниже отклонит интерфейсы с телами методов (за исключением метода статического инициализатора). Попытка эмулировать методы по умолчанию со статическими методами на стороне вызывающего не приведет к тем же результатам, потому что методы по умолчанию могут быть переопределены в подклассах. Retrolambda имеет ограниченную поддержку бэкпортинга методов по умолчанию, но никогда не может быть полностью перенесен обратно, потому что действительно требует новых функций JVM.
Lambdas мог бы работать на Java 7 как есть, если бы там просто существовали необходимые классы API. Инструкция invokedynamic существует в Java 7, но было бы возможно реализовать лямбда-выражения так, чтобы она генерировала лямбда-классы во время компиляции (ранние сборки JDK 8 делали это таким образом), и в этом случае она работала бы на любой версии Java. (Oracle решила использовать invokedynamic для лямбда-выражений для проверки будущего; возможно, однажды JVM будет иметь первоклассные функции, поэтому затем можно изменить invokedynamic, чтобы использовать их вместо генерации класса для каждой лямбды, что повысит производительность.) Что делает Retrolambda, так это что он обрабатывает все эти вызываемые динамические инструкции и заменяет их анонимными классами; так же, как то, что делает Java 8 во время выполнения, когда вызов lamdba вызывается впервые.
Повторение аннотаций - это просто синтаксический сахар. Они совместимы с предыдущими версиями. В Java 7 вам просто нужно реализовать вспомогательные методы (например, getAnnotationsByType ), которые скрывают детали реализации аннотации контейнера, которая содержит повторяющиеся аннотации.
AFAIK, аннотации типов существуют только во время компиляции, поэтому они не должны требовать изменения байт-кода, поэтому достаточно просто изменить номер версии байт-кода скомпилированных классов Java 8, чтобы они работали в Java 7.
Имена параметров метода существуют в байт-коде с Java 7, так что это также совместимо. Вы можете получить доступ к ним, читая байт-код метода и просматривая имена локальных переменных в отладочной информации метода. Например, Spring Framework делает именно это для реализации @PathVariable , поэтому, вероятно, есть библиотечный метод, который вы могли бы вызвать. Поскольку у абстрактных методов интерфейса нет тела метода, эта отладочная информация не существует для методов интерфейса в Java 7, а AFAIK - ни в Java 8.
Другие новые функции - это в основном новые API, улучшения HotSpot и инструментарий. Некоторые из новых API доступны в виде сторонних библиотек (например, ThreeTen- Backport и streamsupport ).
Summa summarum, методы по умолчанию требуют новых функций JVM, но другие языковые функции не делают. Если вы хотите их использовать, вам нужно скомпилировать код в Java 8, а затем преобразовать байт-код с Retrolambda в формат Java 5/6/7. Как минимум, версия байт-кода должна быть изменена, а javac запрещает -source 1.8 -target 1.7
использование ретротранслятора.