Java对象构造期间调用this.getClass()的返回值及安全性问询
Java构造中调用this.getClass()的返回值解析
嘿,这个问题问到点子上了,我来给你详细掰扯清楚:
核心结论
不管是在父类的构造方法里,还是字段初始化表达式中调用this.getClass(),它返回的都是实际被实例化的最派生类(也就是你new出来的那个子类),完全可以放心依赖这个行为。
背后的原因
Java对象的创建流程里,当你new一个子类对象时:
- JVM首先会为整个对象(包含父类+子类的所有字段)分配内存空间
- 紧接着会按从父到子的顺序初始化字段、执行构造方法,但对象的运行时类型从一开始就确定为你new的那个子类了
- 而
getClass()是Object类的final方法,它直接返回对象的实际运行时类型,和当前执行的是父类还是子类的代码无关。
代码示例验证
咱写段代码直观感受下:
class Parent { // 字段初始化时调用getClass() private final Class<?> fieldClass = this.getClass(); public Parent() { System.out.println("Parent构造中getClass()返回:" + this.getClass()); System.out.println("字段初始化的Class值:" + fieldClass); } } class Child extends Parent { public Child() { super(); System.out.println("Child构造中getClass()返回:" + this.getClass()); } } // 测试代码 public class Test { public static void main(String[] args) { new Child(); } }
运行这段代码,输出会是:
Parent构造中getClass()返回:class Child
字段初始化的Class值:class Child
Child构造中getClass()返回:class Child
完全符合我们说的结论,哪怕是在父类的代码逻辑里,getClass()依然指向最派生的子类。
注意事项
虽然getClass()的返回值是可靠的,但要警惕另一个场景:如果在父类构造里调用了被子类重写的非final方法,这时候子类的字段可能还没完成初始化,会导致拿到不正确的字段值——不过这和getClass()本身无关,只是对象初始化顺序带来的坑。
内容的提问来源于stack exchange,提问作者wilx
相关产品推荐
相关产品推荐

