下面是一个快速的代码片段。我可以参考JLS12.4和12.5节中的类加载和初始化过程。只有在访问类的静态变量时才会加载该类,该静态变量不是常量,或者可能正在访问静态方法。在我的例子中,我将变量声明为final,删除final属性,然后将加载check类并运行静态初始化器。以下是修改后的代码
class staticFinalDemo1 {
//static final int var= 100;
static int var= 100;
static final void test() {
System.out.println("Static Final Method Test");
}
static {
System.out.println("Static Initializer");
}
}
class staticFinalDemo2 {
public static void main(String[] args) {
System.out.println(staticFinalDemo1.var);
//staticFinalDemo1.test();
}
} 现在我想说的是,如果我修改最后一条语句,并将其替换为下面的语句。
static final Integer var= 100; 加载静态初始化器。现在这个变量是一个常量。为什么它在这种情况下加载静态初始化器?是不是因为我正在使用一个包装器对象,当我在类中引用它以供使用时,它的实例将被初始化?请澄清这个概念。
本
发布于 2013-07-18 02:10:29
不,这个变量不是编译时常量。常量只能是基元类型或字符串类型。整数不合格。
请参阅JLS §15.28
编译时常量表达式是表示基元类型的值或字符串的表达式,该表达式不会突然完成,并且仅使用以下内容组成:...
发布于 2013-07-18 02:30:18
非常数字段在构造函数中初始化。静态构造函数中的静态字段和实例构造函数中的实例字段。对于您的情况,请尝试将变量设置为Integer类型,并查看bytecode:
class staticFinalDemo1 {
static java.lang.Integer var;
static {};
Code:
0: bipush 100
2: invokestatic #5 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: putstatic #6 // Field var:Ljava/lang/Integer;
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: ldc #7 // String Static Initializer
13: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
16: return
}在第0- 5行,为var字段赋值。bipush将100加载到堆栈,invokestatic创建Integer对象,putstatic将其保存到静态变量。在int类型的情况下,这些行是不存在的。常量池中已存在值。
发布于 2013-07-18 02:14:09
大'I‘整数不是常量,它是对integer对象的引用类型。在java中,你可以互换使用Integer和int,但实际的值是不同的。
https://stackoverflow.com/questions/17707076
复制相似问题