当前位置: 首页 > 面试题库 >

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

薛飞星
2023-03-14
问题内容

考虑下面的小例子:

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中的错误还是公共默认方法在这里重新出现?


问题答案:

getDeclaredMethods()此处的行为正确,因为它可以准确告诉您在类中找到的内容。如果输入interface使用Java
7目标的编译器(或更旧的编译器),您将看不到Java 7实现的输出有所不同getDeclaredMethods()

这是 编译器 ,其行为不同。interface在Java 8中编译此类子程序时,将生成桥接方法,该方法将不会为Java 7目标生成,因为Java
7目标甚至不可能。

现在为接口生成桥接方法的原因是,通常您拥有比接口更多的实现类,因此在接口中使用default桥接方法可以避免将桥接方法添加到每个实现中。此外,如果只有一种abstract方法没有实现的桥接方法,它会使lambda类的生成更加容易。

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



 类似资料:
  • 我们有一个运行在java 7上的服务器端进程:java-version:java version“1.7.0”java(TM)SE运行时环境(build 1.7.0-b147)java HotSpot(TM)64位服务器VM(build 21.0-b17,混合模式) 它接受来自我们自己开发的java应用程序(通过正确签名的JNLP启动)的SSL连接。 通常情况下,不管客户机应用程序是运行在Java

  • 我在windows 7机器上安装了JDK 1.7,在安装JDK 1.8 u20后,出现以下错误: 我的变量指向旧版本(即1.7)。 这里出了什么问题,我如何使用java 8和java 7?

  • Java8引入了重要的新语言特性,如lambda表达式。 语言中的这些变化是否伴随着编译字节码中的重大变化,从而阻止它在不使用某些反向翻译器的情况下在Java7虚拟机上运行?

  • 我有一个抽象类a,类B是扩展a的具体类。 给B班打电话。getDeclaredMethods()除了返回类B的方法签名外,还返回类A的方法签名,但是JAVA文档在 这包括公共、受保护、默认(包)访问和私有方法,但不包括继承的方法 因此,从上面的文档中,我希望从抽象父类继承的方法foo()不应该从调用返回,但我得到的方法foo()是从抽象父类继承的,它是从调用返回的。 谁能给我解释一下这种行为吗。

  • 如果第一点是真的,Java8应用程序将在Java7服务器支持上部署和执行?比如Tomcat 8还是Wildfly?

  • 最近,在使用HttpClient访问Java应用程序中的第三方服务(CURL服务)时,我遇到了如下问题: 我在JDK7中遇到了这个问题。通过对这一问题的研究,我提出了两点建议。 在JDK7TrustStore中添加该特定第三方的证书。[我试过了,但还是遇到了同样的问题] 使用JDK 8而不是JDK 7[我试过了,它对我有效] 单丹