Java 静态初始值设定项和常量包装变量

Java 静态初始值设定项和常量包装变量,java,Java,下面是一段简短的代码。关于类加载和初始化过程,我可以参考JLS第12.4节和第12.5节。仅当您正在访问类的静态变量(该变量不是常量或可能是通过静态方法访问的)时,才会加载该类。在本例中,我将变量声明为final,删除final属性,然后将加载check类并运行静态初始值设定项。下面是修改后的代码 class staticFinalDemo1 { //static final int var= 100; static int var= 100;

下面是一段简短的代码。关于类加载和初始化过程,我可以参考JLS第12.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; 
静态初始值设定项被加载。现在这个变量是一个常数。为什么要加载 在这种情况下是静态初始值设定项吗?是因为我使用了包装器对象及其实例吗 当我在类中引用它以供使用时,会初始化它吗?请澄清这一概念


Ben

不,此变量不是编译时常量。常量只能是基元类型或字符串类型。整数不符合条件

见:

编译时常量表达式是一个表示基元类型的值或字符串的表达式,该值或字符串不会突然完成,并且只使用以下内容组成:[……]


不,此变量不是编译时常量。常量只能是基元类型或字符串类型。整数不符合条件

见:

编译时常量表达式是一个表示基元类型的值或字符串的表达式,该值或字符串不会突然完成,并且只使用以下内容组成:[……]


大“I”整数不是常量,它是整数对象的引用类型。在java中,可以交替使用Integer和int,但实际值不同

大“I”整数不是常量,它是整数对象的引用类型。在java中,可以交替使用Integer和int,但实际值不同

非常量字段在构造函数中初始化。静态构造函数中的静态字段和实例构造函数中的实例字段。对于您的情况,请尝试创建Integer类型的变量并查看字节码:

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类型,则不存在这些行。常量池中已存在值。

非常量字段在构造函数中初始化。静态构造函数中的静态字段和实例构造函数中的实例字段。对于您的情况,请尝试创建Integer类型的变量并查看字节码:

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类型,则不存在这些行。常量池中已存在值。

非常感谢。这很有道理。我现在明白了。欢迎使用javap-cstaticfinaldemo1查看字节码。它有注释,即使没有阅读Java虚拟机规范,也能让事情变得非常清楚。非常感谢。这很有道理。我现在明白了。欢迎使用javap-cstaticfinaldemo1查看字节码。它有注释,即使不阅读Java虚拟机规范,也能让事情变得非常清楚。