public class Test{
int count = 20 ;
{
count = 12;
}
public Test(){
System.out.println(count);
}
public static void main(String[] args) {
new Test();
}}这段代码输出是12;通过javap 可知编译器处理后的类 初始化快没了,count的定义也没有了指定的初始值,
对count的赋值被提取到了构造函数中。就如同下面的代码public class Test{
int count;
public Test(){
count = 20;
count = 12;
System.out.println(count);
}
public static void main(String[] args) {
new Test();
}
}我的问题是下面的代码为什么不会如同上面一样是等效的public class Pro{
int count = age;
int age = 10;
{
count = 12;
}
public Pro(){
System.out.println(count);
}
public static void main(String[] args) {
new Pro();
}
}
public class Pro{
int count;
int age;
public Pro(){
count = age;
age = 10;
count = 12;
System.out.println(count);
}
public static void main(String[] args) {
new Pro();
}
}第一段Pro编译提示向前引用的错误
第二段Pro正常,输出12
之前我还能理解第一段Pro是错的,但是今天看到上面的Test的例子,我又困惑了,
如果说Test那个例子编译器能把第一段Test代码处理后等效于第二段Test代码,
为什么第一段Pro代码不行
public class Test{
{
count = 12;
}
int count = 20 ;
public Test(){
System.out.println(count);
}
public static void main(String[] args) {
new Test();
}
}这样是正确的,为什么呢
count = 12;
}
编译器会最提到构造函数的开头执行。
对象初始化的顺序是先初始化成员变量,在调用构造函数。
父类 -- 静态变量
父类 -- 静态初始化块
子类 -- 静态变量
子类 -- 静态初始化块
父类 -- 变量
父类 -- 初始化块
父类 -- 构造器
子类 -- 变量
子类 -- 初始化块
子类 -- 构造器 你这个没有继承和静态的情况,就可以忽略相关。
所以你的程序执行情况是这样:public class Pro{
int count = age; // 变量-1 age还没定义,所以报错
int age = 10; // 变量-2
{
count = 12; // 初始化块-3
}
public Pro(){
System.out.println(count); // 构造器-4
}
public static void main(String[] args) {
new Pro();
}
}public class Pro{
int count; // 变量-1
int age; // 变量-2
public Pro(){
count = age; // 构造器-3 这里因为age和count都初始化了,默认为0,正确
age = 10; // 重新赋值age为10
count = 12; // 重新赋值count为12,所以最后结果打印为12
System.out.println(count);
}
public static void main(String[] args) {
new Pro();
}
// 打了半天字。。
}