你可能会问,为什么我想这么做 - 因为我正在使用一个类(来自外部库),它会在其静态初始化器中执行某些操作,而我需要知道它是否已经完成。
我查看了 ClassLoader
,但没有找到任何看起来有用的东西。你有什么想法吗?
你可能会问,为什么我想这么做 - 因为我正在使用一个类(来自外部库),它会在其静态初始化器中执行某些操作,而我需要知道它是否已经完成。
我查看了 ClassLoader
,但没有找到任何看起来有用的东西。你有什么想法吗?
ClassLoader.findLoadedClass()
方法。如果返回null,则表示该类未加载。这样,如果未加载类,则不会加载它。
findLoadedClass()
是受保护的,您需要用自己的ClassLoader来覆盖它。if(ClassLoader.getSystemClassLoader().findLoadedClass("java.lang.String") != null){
System.out.println("Yepee, String is loaded !");
}
@irreputable提出了非常好的观点:
“loaded”并不意味着“initialized”。初始化仅发生在由JLS3 $12.4.1定义的精确时刻。
我引用一下:
一个类或接口类型T将在以下任何一个第一次出现之前立即初始化:
- T是一个类并且创建了一个T实例。
- T是一个类并声明了一个静态方法。
- T声明了一个静态字段。
- T使用了一个静态字段,该字段不是常量变量(§4.12.4)。
- T是一个顶级类,并且在其中嵌套了一个
assert
语句(§14.10)。在
Class
类和java.lang.reflect
包中调用某些反射方法也会导致类或接口初始化。 在任何其他情况下,都不会初始化类或接口。
资源:
同一主题:
String
吗?因为它必须评估字符串字面值“java.lang.String”? - Nate W.if
语句不都会始终评估为true
吗? - Nate W.为什么不直接引用类(通过创建引用、创建实例或访问静态成员)?这将会启动类型初始化器,如果它还没有被触发,如果已经被触发,那你仍然可以继续。
System.getProperty
读取参数,我需要知道是否仍然可以更改它们。 - mik01aj我知道现在已经很晚了,但我认为这个答案可能有用。如果你不太害怕(并且被允许)使用sun.misc.Unsafe
类,那么有一个方法可以精确地做到这一点:该方法是
sun.misc.Unsafe.shouldBeInitialized(Class)
如果提供的Class
参数被加载但未初始化,则仅在这种情况下返回true
。
java -verbose Dummy|head
[Opened C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.Comparable from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.CharSequence from C:\Program Files\Java\jre6\lib\rt.jar]
[Loaded java.lang.String from C:\Program Files\Java\jre6\lib\rt.jar]
如果还不算太晚的话.. 这个也应该可以正常工作
Class.forName().newInstance();
newInstance()
方法创建一个由该 Class 对象表示的类的新实例。该类被实例化,就像使用空参数列表的 new 表达式一样。如果尚未初始化该类,则会进行初始化。
Class.forName("com.abc.Xyz", true, this.getClass().getClassLoader())
它将会阻塞直到该类已被初始化(由其自身或其他线程)