2017-05-20 129 views
0

以下代码成功编译。根据我的理解,变量必须在使用前声明,那么究竟发生了什么静态初始化后声明静态变量

class A { 
static { 
    y=20; 
    z=10; 
} 
static int z; 
static int y=30; 
{ 
    w=10; 
} 
int w; 
public static void main(String args[]){ 
    System.out.println(y); 
} 
} 

在阅读注释后修改了问题。 这里的输出是30. 因此变量声明首先发生,然后所有初始化语句按照外观顺序执行

+1

*“根据我的理解,变量必须在使用之前声明”*为什么您认为块和变量的位置在这里很重要? – Tom

+2

*本地*变量必须在第一次使用之前声明。字段,不是很多... –

+1

这两个链接都不作为重复使用,但他们(隐含地)说,字段的位置可能会有所不同:[实例变量声明的放置](// stackoverflow.com/q/218573) // [Java最佳实践 - 是否在类变量之前声明构造函数是一件坏事?](// stackoverflow.com/q/10264447) – Tom

回答

1

变量在使用它们

之前宣布

这只是部分正确。如果你在一个方法,你这样做:

System.out.println(i); 
int i = 0; 

显然它不会编译。

但是,当您在课堂级声明变量时,此规则不成立。在您的代码中,仅仅因为w的声明在其使用后被写入了几行(w = 10;),因此并不意味着该行在线路w = 10;后执行了int w;

可以这样想:编译器首先会看到所有静态字段的声明(类级变量),然后是所有非静态字段,然后是类中的代码块(构造函数,方法等)。在您的代码:

class A { 
    static { 
     z=10; 
    } 
    static int z; 
    { 
     w=10; 
    } 
    int w; 
} 

编译器看到z第一,然后w。那么让我们假设您在代码的其他部分首次访问A。现在执行静态块(z=10;)。我们再假设你实际上正在创建一个A的新实例,现在w=10;会得到执行。

+0

修改完整性问题 – wib

+1

@wib您遇到的行为是因为像'int y = 30;'这样的语句在静态块之后执行。所以编译器首先看到声明,然后运行静态块,然后执行'y = 30'部分。 – Sweeper

1

变量由类加载器在加载类时声明。

静态块将被评估首次类访问,从而在当时的成员变量将被宣布,这样的顺序并不重要

+0

修改了这个问题。变量在一个语句中声明并初始化时会发生什么? – wib