java - java中的静态 block 和静态变量

标签 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);
}

初始化后我定义了变量——“age”,发现它可以工作。它们都是静态的,为什么不按照代码顺序执行。

最佳答案

有两件事您需要考虑。

  1. 初始化顺序(将值分配给字段的顺序)
  2. 范围 - 代码中的字段可以seen

如果我正确地阅读了你的问题,你似乎认为这两件事是相同的,但在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 语言规范中定义。具体来说,它在section 6.3 which defines the scoping rules中:

The scope of a declaration of a member m declared in or inherited by a class type C (§8.1.6) is the entire body of C, including any nested type declarations.

关于java - java中的静态 block 和静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29325151/

相关文章:

java - 对 IntelliJ IDEA 中的 UnsupportedClassVersionError 进行故障排除

java - 刷新 jtable 的内容

java - Play Framework 1.2.4 将项目导出/导入到 Eclipse IDE

java - 在 org.springframework.data.mongodb.core.convert.DefaultDbRefResolver.<c linit>(DefaultDbRefResolver.java :57)

java - org.json.JSONObject 是否违反了 Object.equals() 契约(Contract)?

c# - Java是否允许直接内存访问

java - 为 JToolbar 创建复合 Swing 组件

java - Shaker排序的条形演示一次对所有条形进行排序-Java

c# - 在C#中编译Java文件后如何获取输出的CLASS文件名?

java - 如何获取设备的总存储大小?