java中的静态块和静态变量

时间:2015-03-29 02:58:20

标签: 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”,我发现它是有效的。它们都是静态的,所以为什么不按照代码序列执行它们。

2 个答案:

答案 0 :(得分:2)

您需要考虑两件事。

  1. 初始化顺序(将值分配给字段的顺序)
  2. 范围 - 您的代码中的字段可以通过看到
  3. 如果我正确地阅读了你的问题,你似乎认为这两件事是相同的,但在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

      

    由a声明或继承的成员m的声明范围   类类型C(第8.1.6节)是C的整个主体,包括任何嵌套的类   类型声明。

答案 1 :(得分:1)

根据代码序列执行阻止(你的年龄将是34岁)。

静态字段的定义在开头就解决了一次,所以它们在代码中的位置并不重要。你可以把它放在最后,它仍然可以工作;)