16

我的一个朋友问我哪个会加载第一个静态变量或静态块。

我的答案指向静态变量。

所以他给了我两个方程并说区分它们
第一个方程

public class Some {
    public static void main(String args[])
    {
        System.out.println(Some.x);
    }
    static {
        System.out.println(Some.x);
    }
    static int x=90;
}

开/关:0 90

第二个方程

public class Some {
    public static void main(String args[])
    {
        System.out.println(Some.x);
    }
    static int x=90;
    static {
        System.out.println(Some.x);
    }
}

开/关:90 90

我试图反编译字节码,发现上面两个方程都是一样的。请帮助我区分它们。当静态变量初始化时我很困惑。

4

4 回答 4

8

静态块按照它们在源文件中出现的顺序进行初始化。关于堆栈溢出已经有几个与此相关的问题......这个问题对你有一个很好的答案:Java:静态最终字段的初始化顺序是什么?

于 2013-03-15T08:33:28.303 回答
2

静态变量和静态块按照它们出现的顺序执行。

这里先 O/P: 0 90 作为在System.out.println(Some.x);静态变量初始化语句之后执行的静态块的语句static int x=90;

于 2013-03-15T08:37:20.603 回答
-1

静态变量在 JVM 加载类时执行,类在实例化或调用其静态方法时被加载。

static Initializer 块在类被实例化之前或在其静态方法被调用之前被初始化,甚至在其静态变量被使用之前。

于 2013-03-15T08:40:08.370 回答
-1

我给出了一个简单的例子来说明静态和实例内容的控制流:

假设您有 2 个类 A 和 B。A 类扩展到 B 类。B 类有一个 main 方法。在 cmd 上成功编译两个命令后,如下所示:

java B

现在会发生什么一步一步看:

  1. 将加载 A 类和 B 类
  2. A类的静态成员和块将被识别并顺序执行(一个接一个)(但在类加载时只执行一次)
  3. B类的静态成员和块将被识别并执行(一个一个)(但在类加载时只执行一次)
  4. 将调用 B 类的 main 方法(如果 B 类没有 main 方法,则将调用 A 类的 main 方法)
  5. 一旦您创建了 A 类的对象:所有实例成员的初始化和实例块的执行都将在 A 类中完成
  6. 将执行 A 类的构造函数(用于创建对象)
  7. 如果创建B类的对象:所有实例成员的初始化和实例块的执行都将在A类中完成。
  8. A类的构造函数(默认构造函数或任何其他,如果你从B的构造函数调用它)将被执行

  9. 那么所有实例成员的初始化和实例块的执行都将在 B 类中完成

  10. 之后将执行 B 类的构造函数(用于创建对象)

注意:静态成员和块在第一次加载类时只执行一次,而实例成员和实例块在每次创建类的对象时执行。如果我不正确,请告诉我。

于 2013-03-15T08:51:57.117 回答