关于super.getClass()方法调用返回结果的原因

qianshe223 2011-06-12 10:29:37
看到Java笔试题中有一道关于super的题,题目如下:
下面程序的输出结果是多少?
import java.util.Date;
public class Test extends Date{
public static void main(String[] args) {
new Test().test();
}

public void test(){
System.out.println(super.getClass().getName());
}
}

很奇怪,结果是Test
这属于脑筋急转弯的题目,在一个qq群有个网友正好问过这个问题,我觉得挺有趣,就研究了一下,没想到今天还被你面到了,哈哈。
在test方法中,直接调用getClass().getName()方法,返回的是Test类名
由于getClass()在Object类中定义成了final,子类不能覆盖该方法,所以,在
test方法中调用getClass().getName()方法,其实就是在调用从父类继承的getClass()方法,等效于调用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也应该是Test。
如果想得到父类的名称,应该用如下代码:
getClass().getSuperClass().getName();
————————————————————
以上是题目和分析,我也做了测试,结果确实是Test,但是我看不明白下面的分析,我觉得他说的模棱两可,没有说明白实质问题。
为此,我查阅了Object的getClass()方法的API,解释是:返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
看了这个,我很清楚this.getClass()是返回运行时对象的类型,但是super.getClass()为何返回的还是子类的类型,还是不明白。
后来在网上查了super的含义,有一个帖子说super不是超类的引用,而是表示在子类中调用父类的方法或属性而已,并且给出例子
class B extends A{
public void print(){
System.out.println(super.getClass());//调用A类中的getclass()方法,A是Object的子类,A中的getClass()是Object中的,运行时期的实例是B类,所以输出的依然是Class B
System.out.println(this.getClass()); //调用B类中的getclass()方法,此方法从A继承的,A从Object继承的,运行时期的实例是B类,所以输出的是Class B

/*上面的super.getClass()和this.getClass()都是调用的Object中的getClass(),而super.getClass()和this.getClass()都是通过实例化B类,调用print(),从而调用这两个方法,运行时期的类都是B,Object中的getClass()返回的是运行时期的类 名,所以输出都是Class B
*/
}
我认为后面的解释更加说的通一些,但是我不确定解释是不是正确,所以,发到版上来,请版上的高手帮忙看一下,给出合理的解释。因为这道笔试题的所谓答案也已经被转载了很多次了,如果解释真是不正确了,那就蒙蔽了很多人了。。。

...全文
977 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
麦田 2012-06-20
  • 打赏
  • 举报
回复
这题太模糊了,学习了。
as5879081 2011-10-17
  • 打赏
  • 举报
回复
我是来学习的。看三楼
JeffLau_ 2011-08-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 trocp 的回复:]
按楼主的例子:

第一:不管是T1的getClass()还是Date的getClass(),他们都是非覆盖式的从Object继承来的。

第二:Object的getClass()方法的释义是:返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。

/**
* Returns the runtime ……
[/Quote]


学习了!!!
Mybeautiful 2011-06-13
  • 打赏
  • 举报
回复
trocp 说的十分在理。
qianshe223 2011-06-13
  • 打赏
  • 举报
回复
首先非常感谢高手对该问题的解答!
oO临时工Oo 2011-06-12
  • 打赏
  • 举报
回复

按楼主的例子:

第一:不管是T1的getClass()还是Date的getClass(),他们都是非覆盖式的从Object继承来的。

第二:Object的getClass()方法的释义是:返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。

/**
* Returns the runtime class of this {@code Object}. The returned
* {@code Class} object is the object that is locked by {@code
* static synchronized} methods of the represented class.
**/

释义指出,要返回此Object运行时类,这外当然不可能指Object自己了,否则所有类调用getClass()方法都返回Object.class了。

那到底谁是Object的运行时类呢,不是Object自己,当然就只能是他的儿子、或各种孙子了,到底是谁呢,举个例子:
Date作为直接继承Object的类,作为Object的儿子,如果调用Date.getClass(),返回的是什么呢?在Date中,无论是this.getClass()还是super.getClass(),毫无疑问都指向了Object.getClass()。根据上一段解释,Object.getClass()返回不可能是Object.class,那没得说,只能是Date.class了。

根据上段:new Date()时,Date是Object的运行时类。

同理:根据LZ的例子,new T1()时,运行是类不可能是T1他老子Date,更不会他各种老老子(如Object),只能是自己。

再回到Object.getClass()释义,返回的只能是T1.class

第三:如果想要从T1中得到Date.class,可以用T1.getClass().getSuperClass();
oO临时工Oo 2011-06-12
  • 打赏
  • 举报
回复
按楼主的例子:
第一:不管是T1的getClass()还是Date的getClass(),他们都是非覆盖式的从Object继承来的。
第二:Object的getClass()方法的释义是:返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
什么是运行时类,运行时类是Object的一个实例,注意了,关键来了,他返回的不是Object.class,他返回的是运行时类,就是虚拟机中是谁在运行就是谁,如果你new Date(),Date当然是运行时类,而不是Object,否则所有类的getClass()方法都返回了Object.class 了。
根据上一段解释,Date是Object的子类,Date.getClass()返回的肯定是Date.class,
同样的T1继承Date,假如有一个属于Date的getClass()他返回的也不可能是Date.class,因为当new T1()后,T1是一个运行时类,只不过他拥有Date的资源结构。所以谁被实例化,谁就是一个运行时类。

第三:如果想要从T1中得到Date.class,可以用T1.getClass().getSuperClass();

darker2015 2011-06-12
  • 打赏
  • 举报
回复
大神出来,期待解答...

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧