【问题标题】:Difference static behaviour between MyClass.class and Class.forName(“MyClass”)MyClass.class 和 Class.forName(“MyClass”) 之间的差异静态行为
【发布时间】:2014-06-05 06:06:25
【问题描述】:

我不确定MyClass.classClass.forName("MyClass")之间加载静态变量/块有什么区别,例如,我有下面的类:

package test;
public class SampleClass{
    public static SampleClass instance = new SampleClass();
    private SampleClass(){
       System.out.println("SampleClass Instance Created");
    }
}

然后,在另一个类中,我使用以下方法访问了上面 SampleClass 的类对象:

System.out.println(SampleClass.class);

然后,输出将是:

class test.SampleClass

如果我改用class.forName(),如下:

 System.out.println(Class.forName("test.SampleClass"));

然后,输出将是:

 SampleClass Instance Created
 class test.SampleClass

谁能给我一个解释? 非常感谢。

【问题讨论】:

  • 在这两种情况下您都应该看到“SampleClass Instance Created”。也许它在您的日志中比您预期的要早?
  • this 应该能帮到你
  • @JonSkeet 不幸的是,事实并非如此。 JLS 12.4 清楚地说明了导致类初始化的事件。使用.class 访问类不是这样的事件。所以这两个语句在类加载上是有区别的:只有后者初始化类!
  • @Seelenvirtuose:Doh - 我误读了代码;我以为 OP 正在打印出 instance 本身。我责怪缺乏咖啡。
  • @SotiriosDelimanolis:是的,我误读了代码。对不起!

标签: java class static


【解决方案1】:

Class.forName("MyClass") 的调用导致类在运行时被加载。在类加载器加载类之后,JVM 也会初始化该类,因此 static 块会被执行。

在您的情况下,您有一个静态字段,它是您的类的实例,因为这个静态块被执行,您的对象正在被初始化。这就是您看到 System.out 被打印出来的原因。

.class 语法用于获取被调用类的Class。它实际上并没有加载类。

参考:

【讨论】:

  • 我见过和你一样的来源。 :) 我只是太慢了。 +1
【解决方案2】:

Class.forName() 使用 ClassLoader 并尝试在运行时解析类名,而 .class 在编译时解析。

【讨论】:

  • 确实如此,但并没有解释找到类时是否初始化的区别。请注意,即使使用.class,该类仍会在执行时加载
【解决方案3】:

class.forName() 如果类尚未加载,则使用“调用者”类加载器加载该类。

.class 不加载类。

【讨论】:

  • 使用类文字加载类,但不初始化它。例如,如果您在运行程序之前删除了SampleClass 的类文件,则会因为无法加载该类而失败。
【解决方案4】:

这只是因为Class.forName() 在运行时将您的类动态加载到内存(RAM)中。它将执行该类中的所有静态块,而不创建该类的引用,

来自官方文档:

对 Class.forName("X") 的调用会导致名为 X 的类被动态加载(在运行时)。调用 forName("X") 会导致初始化名为 X 的类(即,JVM 在类加载后执行其所有静态块)。 Class.forName("X") 返回与“X”类关联的 Class 对象。返回的 Class 对象不是“x”类本身的实例。

Class.forName("X") 加载尚未加载的类。 JVM 跟踪以前加载的所有类。这 方法使用调用它的类的类加载器。 “X”是 所需类的完全限定名称。

这里有更多关于它的信息:http://www.xyzws.com/Javafaq/what-does-classforname-method-do/17

【讨论】:

    【解决方案5】:

    感谢以上各位的回答和讨论。

    我以为无论使用 Class.forName() 还是 MyClass.class 都会加载类,显然我错了。但我不明白为什么在使用 MyClass.class 时它不加载类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 1970-01-01
      • 2014-07-25
      相关资源
      最近更新 更多