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”,我发现它是有效的。它们都是静态的,所以为什么不按照代码序列执行它们。
答案 0 :(得分: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语言规范中定义的。具体来说,它位于section 6.3 which defines the scoping rules:
由a声明或继承的成员
m
的声明范围 类类型C
(第8.1.6节)是C
的整个主体,包括任何嵌套的类 类型声明。
答案 1 :(得分:1)
根据代码序列执行阻止(你的年龄将是34岁)。
静态字段的定义在开头就解决了一次,所以它们在代码中的位置并不重要。你可以把它放在最后,它仍然可以工作;)