You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何this.getClass().getName()与StackTraceElement.getClassName()返回结果不同?

问题解惑:为什么ElementModel构造器中getClass()返回BaseModel$1?

这事儿的核心原因其实很简单:你在BaseModel构造器里创建的不是ElementModel本身,而是它的匿名内部子类,咱们一步步拆解:

1. 为什么ElementModel构造器输出BaseModel$1?

看BaseModel构造器里的这段代码:

addedElements = new ElementModel<E>(){};

这里的{}是关键——它表示你创建了一个继承自ElementModel的匿名内部类,而不是直接实例化ElementModel。Java对匿名内部类的命名规则是「外部类名$数字」,因为这个匿名类是在BaseModel里创建的第一个匿名类,所以它的全名就是BaseModel$1。

当这个匿名子类的构造器执行时,this指向的是这个匿名子类的实例,所以this.getClass().getName()自然返回的是这个匿名类的名字,而不是父类ElementModel。

2. 为什么BaseModel构造器输出CellModel?

这是Java继承的正常表现:当你创建CellModel实例时,JVM会先执行父类BaseModel的构造器,此时this指向的是正在初始化的CellModel实例(子类实例初始化过程中,父类构造器里的this始终是子类对象),所以this.getClass().getName()返回CellModel是符合多态规则的。

3. 为什么demo2里st.getClassName()返回ElementModel?

你在demo2里的逻辑是遍历栈轨迹,找到方法名为add的栈帧:

if (st.getMethodName().equalsIgnoreCase("add")) {
    System.out.println("ElementModel::demo2.......st.getClassName: "+st.getClassName());
}

这里的add方法是定义在ElementModel类中的,哪怕是由匿名子类实例调用,栈轨迹里记录的是方法的定义类,所以st.getClassName()返回的是ElementModel。但注意:此时this.getClass().getName()在demo2里其实还是BaseModel$1(你可以自己打印验证),你看到的符合预期只是栈帧的类名,并非当前实例的实际类型。

解决方法:获取真正的ElementModel实例

如果你希望addedElements是ElementModel的实例,只需要把BaseModel构造器里的代码改成:

addedElements = new ElementModel<E>(); // 去掉后面的{}

这样就直接实例化ElementModel本身,而非匿名子类,此时ElementModel构造器里的this.getClass().getName()就会返回ElementModel,符合你的预期。

内容的提问来源于stack exchange,提问作者Tania

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:17:59