当继承遇到反射


起因:使用EventBus库时,只是在父类中注册了监听事件,把this传递过去了:EventBus.getDefault().register(this),子类中并没有注册监听事件,但在响应时调用的却是子类中的响应方法,EventBus是用反射来获取注册监听器的类的方法表然后调用相关方法的,因此写了个继承与反射的例子来分析一下。

/* A.java */
public class A {
    public void foo() {
    }
}
/* B.java */
public class B extends A {

    public void foo() {
    }

    public void foo2() {
    }

    public void foo3() {

    }
}
public class Program {

    public static void main(String[] args) {

        A obj = new B();
        Class<?> clazz = obj.getClass();
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }

    }
}

输出:

foo
foo3
foo2
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll

这里得到的方法列表是B类中的方法。

解释:

因为 A obj = new B() , obj的实际类型是B,obj调用getClass()方法时,由于链接时的动态绑定,obj.getClass()方法被重新定向到了类B#getClass()方法的方法调用入口,所以obj.getClass()实际执行的是B#getClass()函数,因此得到的是B的Class实例。
因此 clazz.getMethods() 得到的自然是类B的方法表了。

关于"this":

在类A中添加方法:

public void fuck() {
        System.out.println(this);
        System.out.println(this.getClass().getName());
    }

在main()方法中调用fuck():

A obj = new B();
obj.fuck();

输出:

test.demo.B@15db9742
test.demo.B

在A类中的this被重新定向到了B类的实例。

解释:

类B继承类A,同对getClass()函数的分析一样,类B在编译时自动拷贝了类A中的所有方法,类B没有显示地重写fuck()函数,因此在类B内也有一份与类A中fuck()函数相同的fuck()函数的拷贝。在执行obj.fuck()时,由于链接时的动态绑定obj.fuck()方法被重新定向到了类B#fuck()方法的方法调用入口,所以obj.fuck(),实际执行的是B#fuck()函数,因此A.java文件中fuck()函数的this是B的实例也就不足为奇了,因为obj.fuck()方法不是调用类A而是调用类B中的fuck()。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 35,094评论 18 399
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 2,155评论 0 9
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,851评论 0 11
  • 教育心理学的核心就是学习理论。关于学习是怎么发生的?有何机理?心理学家们通过各种实验探究,形成了几大流派。巴甫洛夫...
    Li老师阅读 5,978评论 0 5
  • 因病写诗,文友花开热心开药,免费义诊,要求我写一首脸红心跳的诗以抵诊资,戏做而成,也算是为天下有情人而写相思意。 ...
    李榆阅读 341评论 8 6

友情链接更多精彩内容