java中的静态初始化

java中的静态初始化,java,jvm,Java,Jvm,我知道有很多类似的问题,但我想得到一些关于这个问题的详细解释 假设我有这个代码- public class Finalexamples { public int num = 3; public static int num2; public static Finalexamples a; public Finalexamples(){ Finalexamples.num2 = 4; }

我知道有很多类似的问题,但我想得到一些关于这个问题的详细解释

假设我有这个代码-

 public class Finalexamples {

        public int num = 3;
        public static int num2;
        public static Finalexamples a;

        public Finalexamples(){
            Finalexamples.num2 = 4;
        }

        static{
            a = new Finalexamples();
             System.out.println(num2);
             Finalexamples.num2 = 5;
            }

    public static void main(String[] args) {
        System.out.println("Starting...");
    }

}
  • 当JVM加载.class文件时,它是否首先使用默认值初始化静态变量,然后使用文本值运行程序
  • 在我的示例中,静态块输出“4”(固定),如果可以解释为什么不是0
    为什么
    0
    ?它应该输出
    4

    加载类时,静态字段和语句将按显示顺序读取和执行。

    因此,首先执行以下操作:

    public static int num2;
    public static Finalexamples a;
    
    然后调用以下命令:

     static{
              a = new Finalexamples();
              System.out.println(num2);
              Finalexamples.num2 = 5;
          }
    
    这:
    a=newfinalexamples()执行:
    Finalexamples.num2=4


    So
    System.out.println(num2)显示
    4

    为什么
    0
    ?它应该输出
    4

    加载类时,静态字段和语句将按显示顺序读取和执行。

    因此,首先执行以下操作:

    public static int num2;
    public static Finalexamples a;
    
    然后调用以下命令:

     static{
              a = new Finalexamples();
              System.out.println(num2);
              Finalexamples.num2 = 5;
          }
    
    这:
    a=newfinalexamples()执行:
    Finalexamples.num2=4


    So
    System.out.println(num2)
    显示
    4

    Ok,因此首先Java进入类中最顶层的静态声明(将
    num2
    定义为int),然后它将
    a
    定义为
    Finalexamples
    对象。然后它会转到静态块。在静态块中,它看到
    a=newfinalexamples()然后通过构造函数创建
    a
    。(如果它在静态初始化结束之前没有执行此步骤,
    a
    将在结束之前无法访问,因为它没有构造,这是不好的!)因此在变量
    a
    的构造函数中,我们将
    Finalexamples.num2
    设置为4。构造函数完成后,Java返回执行静态块,并打印出
    Finalexamples.num2
    ,现在是4。

    好,所以首先Java进入类中最顶层的静态声明(将
    num2
    定义为int),然后将
    a
    定义为
    Finalexamples
    对象。然后它会转到静态块。在静态块中,它看到
    a=newfinalexamples()然后通过构造函数创建
    a
    。(如果它在静态初始化结束之前没有执行此步骤,
    a
    将在结束之前无法访问,因为它没有构造,这是不好的!)因此在变量
    a
    的构造函数中,我们将
    Finalexamples.num2
    设置为4。构造函数完成后,Java返回执行静态块,并打印出Finalexamples.num2,现在是4。

    首先了解此流(这仅适用于您的程序)

  • 静态变量的初始化

  • 静态块的执行:

    static{
        a = new Finalexamples();
         System.out.println(num2);
         Finalexamples.num2 = 5;
        }
  • 在静态块中初始化
    Finalexamples
    的对象引用“a”时,将调用Finalexamples类的构造函数

  • Finalexamples.main()方法。什么都没有

  • 回答你的问题

    静态变量只在执行开始时初始化一次。在初始化任何实例变量之前,将首先初始化这些变量。它是属于类而不是对象(实例)的变量。类的所有实例共享的单个副本

    它不是
    '0'
    ,因为您正在用Finalexamples的新对象初始化静态块中的对象引用。此时将调用构造函数,并将
    num2
    的值设置为
    4

    我希望这有帮助

    首先了解此流程(仅适用于您的程序)

  • 静态变量的初始化

  • 静态块的执行:

    static{
        a = new Finalexamples();
         System.out.println(num2);
         Finalexamples.num2 = 5;
        }
  • 在静态块中初始化
    Finalexamples
    的对象引用“a”时,将调用Finalexamples类的构造函数

  • Finalexamples.main()方法。什么都没有

  • 回答你的问题

    静态变量只在执行开始时初始化一次。在初始化任何实例变量之前,将首先初始化这些变量。它是属于类而不是对象(实例)的变量。类的所有实例共享的单个副本

    它不是
    '0'
    ,因为您正在用Finalexamples的新对象初始化静态块中的对象引用。此时将调用构造函数,并将
    num2
    的值设置为
    4

    我希望这有帮助

    您好,您的最终输出是5 在java中,第一个部分是类区域,第二个部分是堆区域 类区域块包含三个块 方法区域、静态区域、常量池。静态块在类加载时运行,因此您的静态变量在静态块中创建。它在静态块的运行时初始化,而对于静态变量,不会在java中创建多个副本,因此您可以像这样测试代码

    public class HelloWorld{
    
        public int num = 3;
        public static int num2;
        public static HelloWorld a;
    
        public HelloWorld(){
             System.out.println("Constructor Creation value of num2 "+num2);
             HelloWorld.num2 = 4;
             System.out.println("Variable Initialization in Constructor value of num2 "+num2);
        }
    
        static{
    
             System.out.println("Static bloack execution  value of num2 "+num2);
              a = new HelloWorld();
             HelloWorld.num2 = 5;
             System.out.println("Variable Initialization in Static bloack value of num2 "+num2);
            }
    
    public static void main(String[] args) {
        System.out.println("Starting...");
    }}
    
    嗨,你的最终输出是5 在java中,第一个部分是类区域,第二个部分是堆区域 类区域块包含三个块 方法区域、静态区域、常量池。静态块在类加载时运行,因此您的静态变量在静态块中创建。它在静态块的运行时初始化,而对于静态变量,不会在java中创建多个副本,因此您可以像这样测试代码

    public class HelloWorld{
    
        public int num = 3;
        public static int num2;
        public static HelloWorld a;
    
        public HelloWorld(){
             System.out.println("Constructor Creation value of num2 "+num2);
             HelloWorld.num2 = 4;
             System.out.println("Variable Initialization in Constructor value of num2 "+num2);
        }
    
        static{
    
             System.out.println("Static bloack execution  value of num2 "+num2);
              a = new HelloWorld();
             HelloWorld.num2 = 5;
             System.out.println("Variable Initialization in Static bloack value of num2 "+num2);
            }
    
    public static void main(String[] args) {
        System.out.println("Starting...");
    }}
    

    您的意思是它输出“4”吗?在您的程序中,静态块输出4而不是3。为什么您认为字段分配会在静态块之后运行?不,它不会打印3。它无法打印3,因为代码从未初始化