Class.getDeclaredMethods()疑惑

本文探讨了Java中桥接方法的概念及其实现原理。通过具体示例,解释了为何某些情况下会出现看似多余的重复方法,并提供了检查这些方法是否为编译器自动生成的手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class getDeclaredMethods();
该方法返回当前类中声明的方法,包括public private protected,父类的方法不包括其中。
今天在使用该方法时碰到一个例外

接口

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
	void onApplicationEvent(E event);
}

实现类

public class Application<L> implements ApplicationListener<ContextRefreshedEvent> {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        for (Method method : Application.class.getDeclaredMethods()) {
            System.out.println(method.getName());
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
    }
}
运行代码
输出结果:
main
onApplicationEvent
onApplicationEvent
会发现找到了两个onApplicationEvent方法,但是按道理来说Application内部只有一个方法,
这个时候需要查看一下编译生成的class文件的结果,
javap -c Application.class

Compiled from "Application.java"
public class com.spring.Application<L> implements org.springframework.context.ApplicationListener<org.springframework.context.event.ContextRefreshedEvent> {
  public com.spring.Application();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]) throws java.lang.ClassNotFoundException, java.lang.NoSuchMethodException;
    Code:
       0: ldc           #2                  // class com/spring/Application
       2: invokevirtual #3                  // Method java/lang/Class.getDeclaredMethods:()[Ljava/lang/reflect/Method;
       5: astore_1
       6: aload_1
       7: arraylength
       8: istore_2
       9: iconst_0
      10: istore_3
      11: iload_3
      12: iload_2
      13: if_icmpge     38
      16: aload_1
      17: iload_3
      18: aaload
      19: astore        4
      21: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      24: aload         4
      26: invokevirtual #5                  // Method java/lang/reflect/Method.getName:()Ljava/lang/String;
      29: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      32: iinc          3, 1
      35: goto          11
      38: return

  public void onApplicationEvent(org.springframework.context.event.ContextRefreshedEvent);
    Code:
       0: return

  public void onApplicationEvent(org.springframework.context.ApplicationEvent);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #7                  // class org/springframework/context/event/ContextRefreshedEvent
       5: invokevirtual #8                  // Method onApplicationEvent:(Lorg/springframework/context/event/ContextRefreshedEvent;)V
       8: return
}

可以发现生成的class文件确实有两个onApplicationEvent。
原因是因为public void onApplicationEvent(org.springframework.context.ApplicationEvent);
是桥接方法是由编译器生成。
想要区分可以通过isSynthetic和isBridge来区分

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值