问题是关于 Java 。获取类型的类有三种方法(请注意,代码只是用于演示的片段集合):
Class c1 = Class.forName("com.mypkg.MyClass"); //assumes initialize = true
// - OR -
Class c1 = Class.forName("com.mypkg.MyClass", true/false,
this.getClass().getClassLoader());
Class c2 = com.mypkg.MyClass.class;
// - OR -
import com.mypkg.MyClass;
Class c2 = MyClass.class;
MyClass mc = new MyClass();
Class c3 = mc.getClass();
我的问题是关于初始化。对于方法1,我可以使用boolean参数控制是否初始化类。对于方法3,由于创建了一个对象,显然该类已初始化(对吗?)。
但是方法2呢?如果尚未初始化,那么调用.class
是否会初始化该类?和如何以编程方式进行检查一个类是否已经初始化?
请参阅已接受的解决方案及其评论以获得完整答案。这只是一个总结。
如果尚未初始化,则调用.class
不初始化该类。您可以通过在打印消息的类定义中使用静态块来检查是否正在初始化类。
根据Class.forName
的javadoc,“对forName(”X“)的调用会导致名为X的类被初始化。”。还有两个Class.forName
方法,包括一个接受名为 initialize 的布尔参数的方法。根据javadoc,“仅当initialize参数为true且之前尚未初始化时才初始化类。”
答案 0 :(得分:5)
如何自己测试,看看你的VM做了什么?
只需在所有三种方法中使用此类(在独立运行中,因为它最多只会初始化一次!)
class Example {
static {
System.out.println("Class was initialized!");
}
public static int bananas = 0;
}
有关详细信息 假设要初始化的类时,请参阅http://docs.oracle.com/javase/specs/#12.4.1
粗略地说,一个类应该在
时初始化static
方法static
字段基本上,当你第一次使用实际类的任何东西时,不只是引用它。
但是,例如Example.bananas = 1;
也应该触发类初始化,而不需要实例。
答案 1 :(得分:1)
在字节码级别,对类的引用由ldc
instructions之一加载。 VM规范没有提到类是初始化的,所以可以安全地说VM可能保证这样的引用初始化类,但是请注意VM规范没有要求VM尽可能懒惰地进行初始化。
可以在首次引用和严格要求初始化之间的任何时间合法地初始化该类。