【问题标题】:Why my class is not getting loaded为什么我的课程没有加载
【发布时间】:2016-09-16 02:49:54
【问题描述】:

我对以下代码的输出感到困惑。我知道第一个静态块在类加载后被执行,但为什么我的类 Test6 没有被加载。有人可以澄清一下吗?

package com.vikash.General;

public class Test5 {

    public static void main(String[] args) {
        System.out.println(Test6.FOO);
    }
    static {
        System.out.println("Initializing B");
    }
}
class Test6{

    public static final String FOO = "foo";
    static {
        System.out.println("Initializing A");
    }
}

【问题讨论】:

  • 我得到 o/p Initializing B foo

标签: java class classloader


【解决方案1】:

Test6.FOO 指的是Test6,但该字段是从编译时常量初始化的public static final String,因此它是will be inlined by the compiler,而Test6 根本不需要加载。

【讨论】:

  • 确实如此。删除final 时,将调用静态初始化器
  • @Thilo 你能解释一下“它将被编译器内联”吗?我不明白。这对我来说是新的
  • 实际上,代码变为System.out.println("foo")。编译器用字符串字面量替换对字段的引用。在运行时,这行代码不需要Test6
  • 如果您稍后将Test6.FOO 更改为另一个字符串,这可能会导致问题。 Test5 仍将打印旧版本(除非您还重新编译 Test5)。
【解决方案2】:

Test6 根本没有初始化。

foo 是静态的,这意味着它可以在类初始化之前和加载之后使用。

【讨论】:

  • 我不知道我是否完全理解这个答案,但我很确定这是错误的,并且没有回答这个问题。
  • 因为它没有解释为什么 Test6 没有加载。紧随其后的是 foo is static 的一个令人困惑的解释,此时它与行为无关。实际上这是个问题,尽管 foo 蜜蜂 static,为什么它不加载 Test6 并因此调用 static initializer block
  • 我告诉过你它已经加载到 JVM 中但没有初始化。
  • 所以你是说 foo 可以在类初始化之前和类加载之后使用,但不能在两者之间使用?我真的很困惑你想告诉我们什么以及你指的是哪个类。
【解决方案3】:

这似乎是因为编译器正在内联对字符串文字 "foo" 的引用,所以 JRE 实际上并没有费心加载 Test6 来获取它。

如果您进行如下更改:

public static final String FOO = new String("foo");

然后Test6 类确实被加载(并且它的static 块被执行)。

【讨论】:

  • FOO 不是最终的时,它也适用于文字。但如果它应该是,你的解决方案也可以。
【解决方案4】:

使用类加载器,您将获得所需的输出

Class.forName("<package>.Test6");

【讨论】:

  • 为什么不只是Class&lt;?&gt; foo = Test6.class
  • 任何方法都可以。我只是给它,因为 OP 对类加载问题感到困惑。
  • 并非如此。像System.out.println(Test6.FOO) 这样的表达式通常也会加载类(但在这种情况下不会)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2015-12-24
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多