java - getDeclaredMethods() 在 Java 7 和 Java 8 中的行为不同

标签 java java-8

考虑下面的小例子:

package prv.rli.codetest;

import java.lang.reflect.Method;

public class BreakingInterfaces  {
    interface Base {
        BaseFoo foo();
        interface BaseFoo {           
        }
    }

    interface Derived extends Base {
        DerivedFoo foo();
        interface DerivedFoo extends BaseFoo {

        }
    }

    public static void main(String[] args) {       
        dumpDeclaredMethods(Derived.class);
    }

    private static void dumpDeclaredMethods(Class<?> class1) {
        System.out.println("---" + class1.getSimpleName() + "---");
        Method[] methods = class1.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("----------");
    }
}

如果你用 jdk1.7.0.55 编译上面的例子,输出是:

 ---Derived---
public abstract BreakingInterfaces$Derived$DerivedFoo BreakingInterfaces$Derived.foo()
----------

但是当使用 jdk1.8.0.25 时输出是:

---Derived---
public abstract prv.rli.codetest.BreakingInterfaces$Derived$DerivedFoo prv.rli.codetest.BreakingInterfaces$Derived.foo()
public default prv.rli.codetest.BreakingInterfaces$Base$BaseFoo prv.rli.codetest.BreakingInterfaces$Derived.foo()
----------

有谁知道,这是 jdk1.8.0.25 中的错误还是为什么公共(public)默认方法会在这里重新出现?

最佳答案

getDeclaredMethods() 在这里表现正确,因为它准确地告诉您它在类中找到了什么。如果您输入使用 Java 7 目标(或更旧的编译器)编译的 interface,您将看不到 getDeclaredMethods() 的 Java 7 实现的输出有什么不同。

编译器的行为不同。在 Java 8 中编译此类子接口(interface)时,将生成一个桥接方法,该方法不会为 Java 7 目标生成,因为它甚至不可能为 Java 7 目标生成。

现在为接口(interface)生成桥接方法的原因是你通常有比接口(interface)更多的实现类,因此在接口(interface)中有一个 default 桥接方法可以避免将桥接方法添加到每个实现.此外,如果只有一个 abstract 方法并且没有要实现的桥接方法,它会使 lambda 类的生成变得更加容易。

interface 层次结构需要桥接方法但不提供 default 时,编译器必须使用 LambdaMetafactory.altMetafactory 生成代码而不是 LambdaMetafactory.metafactory指定所需的每个桥接方法。

关于java - getDeclaredMethods() 在 Java 7 和 Java 8 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27013542/

相关文章:

Java 8 将 Map<K, List<V>> 转换为 Map<V, List<K>>

java - Java 中的 Lambda 表达式返回类型

java - hibernate 回调

java - ArrayList 对象

java - 日期不匹配

java - 在 java sdk 中更改语言的 DecimalFormatSymbols 符号

Java:定义新矩形时出现数组语法错误

java - Double.isFinite 实现细节 - 为什么是 DoubleConsts.MAX_VALUE 而不是 Double.MAX_VALUE?

java - 如何对属于两个或多个组的列表中的对象进行分组?

lambda - java 8 lambda 的懒惰但持久的评估