11

你可能会问,我为什么要这样做——因为我正在使用一个类(来自外部库),它在它的静态初始化程序中做一些事情,我需要知道它是否已经完成。

我看了看ClassLoader,但没有发现任何看起来有用的东西。有任何想法吗?

4

7 回答 7

14

您可以使用该ClassLoader.findLoadedClass()方法。如果它返回 null,则该类未加载。这样,如果尚未加载该类,则不会加载它。


警告:此代码在这里实际上不起作用,在系统 ClassLoader 中,findLoadedClass()受保护,您需要使用自己的 ClassLoader 覆盖它。

检查下面的链接On the same topic to check if a class is load with the system 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是一个顶级类,并且执行在词法上嵌套在Tassert中的语句(第 14.10 节)

Class在类和包中调用某些反射方法java.lang.reflect也会导致类或接口初始化。在任何其他情况下都不会初始化类或接口。


资源 :

在同一主题上:

于 2010-09-09T16:39:04.377 回答
4

为什么不直接引用类(通过创建引用、创建实例或访问静态成员)?如果它还没有被触发,那将启动类型初始化器,如果它已经触发了,那么你仍然可以继续使用。

于 2010-09-09T16:39:00.457 回答
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 个类!哇)

于 2010-09-09T16:41:28.487 回答
2

你可以尝试这样的事情:

类 c = new ClassLoader() { 类 c = findLoadedClass(className); }。C;

于 2010-09-09T16:47:02.347 回答
2

我知道已经很晚了,但我认为这个答案可能有用。如果您不太害怕(并且您被允许)使用sun.misc.Unsafe该类,那么有一种方法可以精确地做到这一点:方法

sun.misc.Unsafe.shouldBeInitialized(Class)

true当且仅当Class提供的 as 参数(已加载但)未初始化时才返回。

于 2018-01-24T13:35:14.607 回答
0
Class.forName("com.abc.Xyz", true, this.getClass().getClassLoader())

它将阻塞,直到类被初始化(由它自己或其他线程)

于 2010-09-09T17:08:54.917 回答
0

如果还不算太晚..这也应该可以正常工作

 Class.forName().newInstance();

newInstance()创建此 Class 对象表示的类的新实例。该类被实例化为一个带有空参数列表的新表达式。如果尚未初始化该类,则将其初始化。

于 2016-08-31T13:34:11.230 回答