getDeclaredMethods() behaving differently in Java 7 vs. Java 8

后端 未结 2 1901
孤城傲影
孤城傲影 2020-12-06 16:55

Consider the following little example:

package prv.rli.codetest;

import java.lang.reflect.Method;

public class BreakingInterfaces  {
    interface Base {
          


        
相关标签:
2条回答
  • 2020-12-06 17:21

    Pardon the furstration, but it must be in a parallel universe where the Javadoc wording adequately explains this behavior: https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredMethods--. An array of "all the declared methods" turns out to be an array of "all declared methods by the user and by some under-the-hood implementation detail explained on StackOverflow". Even worse, I'm seeing something weird about annotations: I'm overriding a generic method while applying an annotation, and both abstract&default methods returned by getDeclaredMethods() have the annotation, but only the abstract one has the correct non-generic parameters. So it seems to me this implementation detail partly defeats the purpose of searching for a method by annotation.

    0 讨论(0)
  • 2020-12-06 17:43

    getDeclaredMethods() behaves correctly here as it tells you exactly what it has found in the class. If you feed in an interface compiled with Java 7 target (or an older compiler) you will see no difference to the output of the Java 7 implementation of getDeclaredMethods().

    It’s the compiler which behaves differently. When compiling such a sub-interface in Java 8, a bridge method will be generated which will not be generated for a Java 7 target as it is not even possible for the Java 7 target.

    The reason why bridge methods are generated for interfaces now is that you usually have more implementation classes than interfaces, therefore having a default bridge method in the interface saves you from adding that bridge method to every implementation. Further, it makes lambda class generation much easier if there is only one abstract method and no bridge method to implement.

    When an interface hierarchy requires bridge methods but provides no defaults, the compiler has to generate code using LambdaMetafactory.altMetafactory rather than LambdaMetafactory.metafactory specifying every bridge method that is required.

    0 讨论(0)
提交回复
热议问题