在子类构造函数中调用 getClass() 是否始终安全?

2022-09-03 07:28:44

一篇关于类加载的文章指出,方法 getClass() 不应该在构造函数中调用,因为:

对象初始化只有在构造函数代码退出时才能完成。

他们给出的例子是:

public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(getClass().getClassLoader()); // should not call getClass() because object
                                            //    initialization will be complete only at
                                            //    the exit of the constructor code.
    }
}

但是,据我所知,本机 final 方法将始终返回该对象实例的 java.lang.Class 对象,无论它在何处调用(是否在构造函数中)。getClass()

在构造函数中调用给我们带来问题吗?getClass()

如果是这样,在构造函数中调用会给我们带来错误的例子是什么?getClass()


答案 1

在构造函数中调用 getClass() 会给我们带来问题吗?如果是这样,在构造函数中调用getClass()会给我们带来错误的例子是什么?

以这种方式在构造函数中使用将始终导致编译错误,因为在调用之前无法引用。getClass()thissuper()

Main.java:17: error: cannot reference this before supertype constructor has been called
        super(getClass().getClassLoader()); // should not call getClass() because object
              ^
1 error

您可以在 http://ideone.com/B0nYZ1 上自行测试。

已准备就绪,但该实例不能用于引用。ClassClass

不过,您可以在构造函数中使用引用,但您必须以稍微不同的方式执行此操作:Classsuper(MyClassLoader.class.getClassLoader())

此外,在调用超类型构造函数,您可以自由使用构造函数 - 正如您已经指出的那样,在此之后对象基本准备就绪,并且可以从实例中推断出引用。getClass()Class


答案 2
$ javac whose/MyClassLoader.java
whose/MyClassLoader.java:5: error: cannot reference this before supertype constructor has been called
        super(getClass().getClassLoader());
              ^
1 error

我知道今天已经很晚了。