Os métodos padrão requerem essas alterações no bytecode e na JVM que seriam impossíveis de executar no Java 7. O verificador de bytecode do Java 7 e abaixo rejeitará as interfaces com os corpos do método (exceto o método inicializador estático). Tentar emular métodos padrão com métodos estáticos no lado do chamador não produziria os mesmos resultados, porque os métodos padrão podem ser substituídos nas subclasses. O Retrolambda possui suporte limitado para os métodos padrão de backport, mas nunca pode ser totalmente portado porque realmente requer novos recursos da JVM.
Os lambdas podem ser executados no Java 7 como estão, se as classes de API necessárias existirem lá. A instrução invokedynamic existe no Java 7, mas teria sido possível implementar lambdas para gerar as classes lambda em tempo de compilação (as primeiras compilações do JDK 8 fizeram dessa maneira) e, nesse caso, funcionaria em qualquer versão do Java. (A Oracle decidiu usar invokedynamic para lambdas para provas futuras; talvez um dia a JVM tenha funções de primeira classe, então o invokedynamic pode ser alterado para usá-las em vez de gerar uma classe para cada lambda, melhorando assim o desempenho.) O que a Retrolambda faz é que processa todas essas instruções dinâmicas invocadas e as substitui por classes anônimas; o mesmo que o Java 8 faz no tempo de execução quando um lamdba invokedynamic é chamado pela primeira vez.
Repetir anotações é apenas açúcar sintático. Eles são compatíveis com bytecode com versões anteriores. No Java 7, você só precisa implementar os métodos auxiliares (por exemplo, getAnnotationsByType ) que ocultam os detalhes de implementação de uma anotação de contêiner que contém as anotações repetidas.
AFAIK, anotações de tipo existem apenas no tempo de compilação, portanto, não devem exigir alterações de bytecode; portanto, basta alterar o número da versão do bytecode das classes compiladas Java 8 deve ser suficiente para fazê-las funcionar no Java 7.
Os nomes de parâmetro do método existem no bytecode com Java 7, portanto, isso também é compatível. Você pode obter acesso a eles lendo o bytecode do método e observando os nomes de variáveis locais nas informações de depuração do método. Por exemplo, o Spring Framework faz exatamente isso para implementar @PathVariable , portanto, provavelmente existe um método de biblioteca que você poderia chamar. Como os métodos de interface abstrata não têm um corpo de método, essas informações de depuração não existem para os métodos de interface no Java 7 e o AFAIK nem no Java 8.
Os outros novos recursos são principalmente novas APIs, melhorias no HotSpot e ferramentas. Algumas das novas APIs estão disponíveis como bibliotecas de terceiros (por exemplo, ThreeTen-Backport e streamsupport ).
Resumo, métodos padrão requerem novos recursos da JVM, mas os outros recursos de idioma não. Se você quiser usá-los, precisará compilar o código no Java 8 e depois transformar o bytecode com Retrolambda para o formato Java 5/6/7. No mínimo, a versão do bytecode precisa ser alterada e o javac não permite -source 1.8 -target 1.7
que seja necessário um retrotranslator.