Object类中getClass(返回运行时类对象)到底怎么理解

zhebin001 2016-09-18 10:34:17

package com.avicit.zq.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Created by admin on 2016/9/18.
*/
public class Main extends A{
public static void main(String[] args) {
Main t = new Main();
t.dot();
}
}
class A {
private Class t = getClass();//referenced to Class Main (1)
protected Log logger = LogFactory.getLog(t);
B b = new B();
public void dot(){
System.out.println(t.getName());
b.dot();
}
}

class B{
private Class t = getClass();//referenced to Class B (2)
protected Log logger = LogFactory.getLog(t);
public void dot(){
System.out.println(t.getName());
}
}


//output:
com.avicit.zq.test.Main
com.avicit.zq.test.B



有谁能告诉我为啥(1)处的getClass()得到的是父类Main的Class对象,(2)处的getClass()得到的是自身的Class对象?
Object中关于getClass()的解释为:返回运行时类的对象。
坐等高手回答。
...全文
1472 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39936465 2020-02-11
  • 打赏
  • 举报
回复
引用 8 楼 zhebin001 的回复:
[quote=引用 7 楼 windowsoahil 的回复:] 因为通过new关键字创建的对象类型是Main,改成new一个A就会输出类型A
能解释一下为什么吗?这跟“运行时对象”有什么关联吗?[/quote] main继承a,main里有变量t,父类a中的同名变量t会无效,所以t.getname只会用main里的t变量,而b是单独类,所以t还是b自己的变量。这个是基本常识,要牢记。
suhuannan 2020-02-11
  • 打赏
  • 举报
回复
先纠正一点,A是父类,Main 是子类。
这个运行结果正确的,分析这个程序要明白俩点
1.一个类创建对象的同时,jvm会自动创建一个与该类有关的Class 对象。就你提到运行时Class 对象,注意jvm只有一个Class 对象,只不过这个Class对象的实体会随程序运行时而变化。
2.程序加载顺序先父类后子类。

我按照我的思路分析一下运行结果
Main t=new Main()即用子类Main 创建对象,jvm 会先加载父类A,同时也会创建一个与A类有关的Class 对象,然后加载子类Main ,同时之前的Class 对象的实体就变成与Main 类有关了。然后对象t调用dot ()方法,输出此时的Class对象的名字也就是Main类的全类名。再然后对象b调用dot ()方法时,会用B类创建对象,那个Class对象的实体就又变成了与B类有关的了,再输出全类名也就是B的全类名了
suhuannan 2020-02-11
  • 打赏
  • 举报
回复
先纠正一点,A是父类,Main 是子类。
这个运行结果正确的,分析这个程序要明白俩点
1.一个类创建对象的同时,jvm会自动创建一个与该类有关的Class 对象。就你提到运行时Class 对象,注意jvm只有一个Class 对象,只不过这个Class对象的实体会随程序运行时而变化。
2.程序加载顺序先父类后子类。

我按照我的思路分析一下运行结果
Main t=new Main()即用子类Main 创建对象,jvm 会先加载父类A,同时也会创建一个与A类有关的Class 对象,然后加载子类Main ,同时之前的Class 对象的实体就变成与Main 类有关了。然后对象t调用dot ()方法,输出此时的Class对象的名字也就是Main类的全类名。再然后对象b调用dot ()方法时,会用B类创建对象,那个Class对象的实体就又变成了与B类有关的了,再输出全类名也就是B的全类名了
qybao 2019-12-03
  • 打赏
  • 举报
回复
改一下楼主的代码,LZ好好想一下注释部分的问题吧,想通了就明白了

public class Main extends A {
public static void main(String[] args) {
Main t = new Main();
t.dot();
}
}
class A {
private Class t = getClazz();//referenced to Class Main (1)改一下这里,如果明白new子类,this是子类对象,那就理解t为啥是Main
B b = new B();
public void dot(){
System.out.println(t.getName());
b.dot();
}
public Class<?> getClazz() {//用另外一个方法来看
return this.getClass(); //子类继承父类,new子类,LZ觉得this是子类对象还是父类对象?如果是父类对象,那super还有什么意义?
}
}

class B{
private Class t = getClass();//referenced to Class B (2)
public void dot(){
System.out.println(t.getName());
}
}
jiawenhe123 2019-12-03
  • 打赏
  • 举报
回复
x.getClass()方法返回的是x对象的Class,就是说不管这个x的多态表示形式是什么,返回的一定是其实际对象的Class。 这是Java实现动态分派的关键。例如 List<E> list=new ArrayList<>();list.getClass()就是ArrayList.class,而不是List.class, list.add(e)方法一定是ArrayList应该具有的方法,如果没有则会在继承链上递归查找(在Java8以后默认方法可能出现菱形歧义,可查看文档说明)。 理解Java运行时的机制可以结合代理机制做深入的了解。
程序员面试鸭 2019-12-02
  • 打赏
  • 举报
回复
你是在Main类里创建了Main类的对象,由于这样调用者就是Main里的对象呀,getClass()方法在Object类里是final的就是限定子类不能重写,第一个是对象t调用getClass(),显然返回t的所属类的类型com.avicit.zq.test.Main,第二个是你创建了B的对象去调用getClass(),所以就是返回B的对象的类的类型com.avicit.zq.test.B,说白了就是什么对象调用getClss就返回这个对象所属类的类型,如果你想获取父类的类型可以:t.getClass().getSupperClass().getName()这样获取t对象的父类类名:com.Bavicit.zq.test.A
活在梦里吗 2019-12-02
  • 打赏
  • 举报
回复
你这个是本地方法,要是想第一个输出A就换成A.class
qq_39936465 2019-12-02
  • 打赏
  • 举报
回复
引用 8 楼 zhebin001 的回复:
[quote=引用 7 楼 windowsoahil 的回复:] 因为通过new关键字创建的对象类型是Main,改成new一个A就会输出类型A
能解释一下为什么吗?这跟“运行时对象”有什么关联吗?[/quote] getClass就是得到的是当前类,你初始化的是Main类,所以父类A中的t值是Main而不是A。
zhebin001 2016-09-18
  • 打赏
  • 举报
回复
引用 7 楼 windowsoahil 的回复:
因为通过new关键字创建的对象类型是Main,改成new一个A就会输出类型A
能解释一下为什么吗?这跟“运行时对象”有什么关联吗?
解开者 2016-09-18
  • 打赏
  • 举报
回复
因为通过new关键字创建的对象类型是Main,改成new一个A就会输出类型A
zhebin001 2016-09-18
  • 打赏
  • 举报
回复
引用 5 楼 qq_35209952 的回复:
[quote=引用 4 楼 zhebin001 的回复:] 呃呃,犯二了,那把“父类”两个字去掉~
那就更没问题了呀.. 这个对象本来就是Main这个类的呀.. 只是继承了父类的这个方法... 你是想要这两个方法的效果吗.. t.getSuperclass() t.getGenericSuperclass()[/quote] 我觉得您可能没有明白我的意思,A类和B类同样有一个私有变量,值同样为getClass()[同this.getClass()],为啥getClass()返回的值并不是预期的 A类和B类,而是Main类和B类。 就是我想的返回结果是:
com.avicit.zq.test.A
com.avicit.zq.test.B
实际返回结果是:
com.avicit.zq.test.Main
com.avicit.zq.test.B
逗泥丸的平方 2016-09-18
  • 打赏
  • 举报
回复
引用 4 楼 zhebin001 的回复:
呃呃,犯二了,那把“父类”两个字去掉~
那就更没问题了呀.. 这个对象本来就是Main这个类的呀.. 只是继承了父类的这个方法... 你是想要这两个方法的效果吗.. t.getSuperclass() t.getGenericSuperclass()
zhebin001 2016-09-18
  • 打赏
  • 举报
回复
引用 3 楼 qq_35209952 的回复:
[quote=引用 2 楼 zhebin001 的回复:] [quote=引用 1 楼 qq_35209952 的回复:] 有谁能告诉我为啥(1)处的getClass()得到的是父类Main的Class对象 你在说什么.. 你自己写的 extends A 你自己写的输出.. //output: com.avicit.zq.test.Main
输出不是我自己写的,我只是把运行结果粘贴出来了,我对运行结果有异议。[/quote] 我指的是你的描述有问题.. 什么叫父类Main .. 你不是写的 Main继承A么. [/quote] 呃呃,犯二了,那把“父类”两个字去掉~
逗泥丸的平方 2016-09-18
  • 打赏
  • 举报
回复
引用 2 楼 zhebin001 的回复:
[quote=引用 1 楼 qq_35209952 的回复:] 有谁能告诉我为啥(1)处的getClass()得到的是父类Main的Class对象 你在说什么.. 你自己写的 extends A 你自己写的输出.. //output: com.avicit.zq.test.Main
输出不是我自己写的,我只是把运行结果粘贴出来了,我对运行结果有异议。[/quote] 我指的是你的描述有问题.. 什么叫父类Main .. 你不是写的 Main继承A么.
zhebin001 2016-09-18
  • 打赏
  • 举报
回复
引用 1 楼 qq_35209952 的回复:
有谁能告诉我为啥(1)处的getClass()得到的是父类Main的Class对象 你在说什么.. 你自己写的 extends A 你自己写的输出.. //output: com.avicit.zq.test.Main
输出不是我自己写的,我只是把运行结果粘贴出来了,我对运行结果有异议。
逗泥丸的平方 2016-09-18
  • 打赏
  • 举报
回复
有谁能告诉我为啥(1)处的getClass()得到的是父类Main的Class对象 你在说什么.. 你自己写的 extends A 你自己写的输出.. //output: com.avicit.zq.test.Main
Pink_Krystal 2016-09-18
  • 打赏
  • 举报
回复
你在A调getclass方法 根据多态的特性会执行main的getclass方法(因为new的是main 而main继承A) 如果你把main方法里面的Main t = new Main();改成A t = new A();就会得到你想要的结果。 我是菜鸟,不对勿喷
逗泥丸的平方 2016-09-18
  • 打赏
  • 举报
回复
引用 6 楼 zhebin001 的回复:
[quote=引用 5 楼 qq_35209952 的回复:] [quote=引用 4 楼 zhebin001 的回复:] 呃呃,犯二了,那把“父类”两个字去掉~
那就更没问题了呀.. 这个对象本来就是Main这个类的呀.. 只是继承了父类的这个方法... 你是想要这两个方法的效果吗.. t.getSuperclass() t.getGenericSuperclass()[/quote] 我觉得您可能没有明白我的意思,A类和B类同样有一个私有变量,值同样为getClass()[同this.getClass()],为啥getClass()返回的值并不是预期的 A类和B类,而是Main类和B类。 就是我想的返回结果是:
com.avicit.zq.test.A
com.avicit.zq.test.B
实际返回结果是:
com.avicit.zq.test.Main
com.avicit.zq.test.B
[/quote] 我觉得我已经说清楚了.. 运行时Main对象就是Main的. 如果你 new A()的话 才是A的. 如果要父(超)类的类型的话,就用我给的那两个. 一个是直接父类,另一个是最顶级的父类
解开者 2016-09-18
  • 打赏
  • 举报
回复
引用 8 楼 zhebin001 的回复:
[quote=引用 7 楼 windowsoahil 的回复:] 因为通过new关键字创建的对象类型是Main,改成new一个A就会输出类型A
能解释一下为什么吗?这跟“运行时对象”有什么关联吗?[/quote] getClass方法返回对象的类型,而面向对象语言的多态特性决定对象的类型只能在运行期确定(不同于声明的引用类型) 在这里就是用new关键字创建的是Main对象,getClass返回的当然也是Main

62,612

社区成员

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

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