Java 中的静态块和静态变量


class Person{
    public static String name="Mr.zhang";
    //public static int age;
    static{
        age=20;
        System.out.println("initiate age");
    }
    public static int age;
    public static String address;
    static{
        address="beijing";
        age=34;
    }
public static void main(String[] args){
    System.out.println(name);
    System.out.println(age);
    System.out.println(address);
}

我在变量启动后定义了变量——"年龄",我发现它有效。它们都是静态的,所以为什么它们不按照代码序列执行。

您需要考虑两件事。

  1. 初始化顺序(将值分配给字段的顺序(
  2. 范围 - 在代码中可以看到字段的位置

如果我没看错你的问题,你似乎认为这两件事是相同的,但在 Java 中,它们是分开的。

尽管初始化本身是按照源代码行的顺序排列的,但这不适用于字段的范围。字段在类的整个主体中都在范围内,也是在声明之前。

(

同样,对于方法(或任何其他类型的成员( - 可以调用在调用点之后声明的方法。

由于它在范围内(甚至在声明之前(,因此可以在源文件中的任何位置分配给字段。您可以在源代码中类文件的末尾声明所有字段,这不会有什么区别。

这可能会令人困惑的一点是,当您在声明字段的同时进行分配时。喜欢这个:

public class Snippet {
    static {
        a = 20;
    }
    private static int a = 10;
    static {
        System.out.println(a);
    }
    public static void main(String[] args) {
        System.out.println(Snippet.a);
    }
}

但这并不令人困惑 - 只需将声明和赋值视为两个独立的东西 - 声明在整个类的范围内,但赋值是按源代码的顺序执行的。因此,private static int a = 10;可以看作是:

private static int a;
static {
    a = 10;
}

为了给您一个背景参考,这一切都在 Java 语言规范中定义。具体来说,它在定义范围规则的第 6.3 节中:

成员声明的范围m在 类类型C(§8.1.6(是C的整个主体,包括任何嵌套的 类型声明。

块根据代码顺序执行(您的年龄将是 34 岁(。

静态字段的定义在开始时只解析一次,因此它们在代码中的位置无关紧要。你可以把它放在最后,它仍然可以;)

最新更新