你可能会问,为什么我要这样做 - 这是因为我正在使用一个类(来自外部库),它在静态初始化器中执行操作,我需要知道它是否已经完成。
我看了ClassLoader
,但没有找到任何有用的东西。有什么想法吗?
答案 0 :(得分:14)
您可以使用ClassLoader.findLoadedClass()
方法。如果它返回null,则不加载该类。这样,如果类尚未加载,则不加载该类。
警告:此代码在此处不起作用,在系统ClassLoader中,findLoadedClass()
受到保护,您需要使用自己的ClassLoader覆盖它。
检查下面的链接在同一主题上检查是否已使用系统ClassLoader加载类
if(ClassLoader.getSystemClassLoader().findLoadedClass("java.lang.String") != null){
System.out.println("Yepee, String is loaded !");
}
来自@irreputable的非常好的一点:
“已加载”并不意味着“已初始化”。初始化仅发生在JLS3 $ 12.4.1
定义的精确时刻
我引用:
类或接口类型 T 将在第一次出现以下任何一个之前立即初始化:
- T 是一个类,并且创建了 T 的实例。
- T 是一个类,并且调用 T 声明的静态方法。
- 分配 T 声明的静态字段。
- 使用 T 声明的静态字段,该字段不是常量变量(§4.12.4)。
- T 是一个顶级类,并且执行 T 中词法嵌套的
assert
语句(§14.10)。调用类
Class
和包java.lang.reflect
中的某些反射方法也会导致类或接口初始化。在任何其他情况下,不会初始化类或接口。
资源:
ClassLoader.findLoadedClass()
关于同一主题:
答案 1 :(得分:4)
为什么不直接引用该类(通过创建引用,创建实例或访问静态成员)?如果它还没有被解雇,那么它将启动类型初始化程序,如果它已经存在,那么你仍然可以继续。
答案 2 :(得分:2)
您可以使用-verbose标志让JVM在加载类时打印出类。这可能对你有所帮助。
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]
(顺便说一句,刚刚在Hello World程序中尝试了这个,它加载了309个类!哇)
答案 3 :(得分:1)
您可以尝试这样的事情:
Class c = new ClassLoader(){Class c = findLoadedClass(className); } .C;
答案 4 :(得分:1)
我知道现在已经很晚了,但我认为这个答案可能会有用。如果你不是太害怕(并且你被允许)使用sun.misc.Unsafe
类,那么正好的方法就是这样:方法
sun.misc.Unsafe.shouldBeInitialized(Class)
当且仅当作为参数提供的true
(已加载但未初始化)时,才会返回Class
。
答案 5 :(得分:0)
Class.forName("com.abc.Xyz", true, this.getClass().getClassLoader())
它将一直阻塞,直到该类被初始化(通过它自己或其他一些线程)
答案 6 :(得分:0)
如果不是太晚..这应该也可以正常工作
Class.forName().newInstance();
newInstance()
创建此Class对象所表示的类的新实例。该类实例化为具有空参数列表的新表达式。如果尚未初始化,则初始化该类。