为什么执行静态块时这个Float常量为空?

18
执行以下代码后,输出的是“nitesh null”,而不是预期的“nitesh 130”。为什么在执行静态代码块之前没有初始化变量n
class test
{
      static
      {
             System.out.println(test.str+"   "+test.n);
      }
      final static String str="nitesh";
      final static Float n=130f;
      public static void main(String []args)
      {
      }
}

8
这个问题应该被关闭,因为JonSkeet已经回答了它。 - user3459110
1个回答

25

str是一个编译时常量 - n不是,因为它的类型是Float。如果你将其改为final static float n = 130f,然后你会在静态初始化块中看到值。

所以当前,在静态初始化块中,实际上正在内联str的值 - 你的代码等同于:

System.out.println("nitesh   "+test.n);

来自JLS第15.28节(常量表达式)

常量表达式是一个表示原始类型值或不会突然完成并且仅使用以下内容组成的字符串:[...]

Float不是原始类型。

此外,即使没有内联,常量变量str也在任何静态初始化程序块被执行之前被初始化。 来自JLS第12.4.2节(类初始化详细信息)

  • ...
  • 然后,初始化C的静态字段,这些字段是常量变量(§4.12.4,§8.3.2,§9.3.1)。
  • ...
  • 接下来,按照文字顺序执行类变量初始化程序和静态初始化程序,或者接口的字段初始化程序,就像它们是单个块一样。

@任务:不,那绝不是我所说的简短版本。这与哪些变量实际上是编译时常量有关,它们的值在使用它们的地方被内联。 - Jon Skeet
糟糕!需要花更多时间来使用JavaDoc。感谢您的澄清。对了,因为您的回答加10分。 - akash
6
不,float 是一个原始类型,而 Float 是一个包装类。它们是不同的。 - Jon Skeet
静态初始化块在static final变量初始化之前运行吗?为什么?太惊讶了... - ikh
1
这意味着将静态块移动到声明之后也可以解决问题。 - JAB
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接