初始化块的问题?

时间:2021-09-23 19:41:02
public class Test {
 
{
System.out.println(age);
age=6;
System.out.println(age);
}
int age=8;
public static void main(String[] args) {
System.out.println(new Test().age);

}
}
为什么int age=8;在初始化块的下面定义,会报错。上面在执行初始化块时系统不是已经为该实例属性赋了一个默认初值0吗?

10 个解决方案

#1


初始化块,我的理解是,它不是一个方法,而是在类加载到此地时就执行,也就是说,它的执行是顺序的。

比喻private int a = 0; private int b = a+1;不会出错,但是这两个反过来就错误了,这是同样的道理。

#2


说的不好,可以这样理解:类实质上也是一个方法,加载它的变量时,若涉及到其他变量,那么被涉及到的变量必须已经被加载。

#3


我是这样理解的:在类初始化的时候就加载了块,那个时候age还没有定义,程序根本就不认识他,因为程序执行是有顺序的。如果把age的定义放在块的上面就正确啦!其实和2楼的是一个意思的。

#4


java中除变量定义时可以给变量赋值,其它语句只能写在方法中或者块中。

public class Test { 
 int age;

System.out.println(age); 
age=6; 
System.out.println(age); 

//int age=8; 
public static void main(String[] args) { 
System.out.println(new Test().age); 



#5


路过

#6


初学者的答案:

就和二楼说的一样
要改的话,就会像4楼一样

#7


学JAVA永远要记得成员变量和局部变量的区别,成员变量也就是定义类时所定义的一些满足对象生成的初始化的变量,而局部变量则是定义方法时满足方法体时所设计的变量。很显然据你所指的你的是成员变量,成员变量一定要先声明也就是先定义,这样也就是在我们计算机的堆内存里占个地,然后才开始赋值,真正意义上在计算机的内存里占了空间,最后才通引用这个变量,即通过变量名来取得刚占内存空间里的那个值,你不通声明两个一样的成员变量,即变量的类型,变量的名字,变量的值都一样,这样编译时计算机当然报错,计算机不知道你要用的是哪个,即认不得两个一模一样的 age=6; int age=8; 
为什么int age=8;在初始化块的下面定义,会报错。上面在执行初始化块时系统不是已经为该实例属性赋了一个默认初值0吗?你把age=6;放上面,你认为对吗,你还没有定义即没有声明一个变量显然违反了变量的生成规则,编译器不报错才怪呢,把int age=8;放上面OK,然后要重新给变量age赋值,可以直接age=6;因为变量age已经声明过了,即定义过了,是int类型,无需也不能再重新定义,即int age=6;这样就等于定义了两个一样的变量,编译器同样会报错,不知道你明白了没

#8


up

#9


是的,应该吧int age=8;放在块的上面。

#10


额,对于这一点的话,如果你在age前面加个this就可以编译通过了。
即System.out.println(this.age);
其实这点我也有点疑惑,在没有this关键字前缀的情况下编译器报出的错误为不能在其定义前引用,而加了this关键字它就可以通过编译了。
而且前输出为0,后输出为6。
我想跟编译器处理上有关,如果你不加this关键字,编译器无法识别在age定义之前到底为成员变量还是局部变量。

#1


初始化块,我的理解是,它不是一个方法,而是在类加载到此地时就执行,也就是说,它的执行是顺序的。

比喻private int a = 0; private int b = a+1;不会出错,但是这两个反过来就错误了,这是同样的道理。

#2


说的不好,可以这样理解:类实质上也是一个方法,加载它的变量时,若涉及到其他变量,那么被涉及到的变量必须已经被加载。

#3


我是这样理解的:在类初始化的时候就加载了块,那个时候age还没有定义,程序根本就不认识他,因为程序执行是有顺序的。如果把age的定义放在块的上面就正确啦!其实和2楼的是一个意思的。

#4


java中除变量定义时可以给变量赋值,其它语句只能写在方法中或者块中。

public class Test { 
 int age;

System.out.println(age); 
age=6; 
System.out.println(age); 

//int age=8; 
public static void main(String[] args) { 
System.out.println(new Test().age); 



#5


路过

#6


初学者的答案:

就和二楼说的一样
要改的话,就会像4楼一样

#7


学JAVA永远要记得成员变量和局部变量的区别,成员变量也就是定义类时所定义的一些满足对象生成的初始化的变量,而局部变量则是定义方法时满足方法体时所设计的变量。很显然据你所指的你的是成员变量,成员变量一定要先声明也就是先定义,这样也就是在我们计算机的堆内存里占个地,然后才开始赋值,真正意义上在计算机的内存里占了空间,最后才通引用这个变量,即通过变量名来取得刚占内存空间里的那个值,你不通声明两个一样的成员变量,即变量的类型,变量的名字,变量的值都一样,这样编译时计算机当然报错,计算机不知道你要用的是哪个,即认不得两个一模一样的 age=6; int age=8; 
为什么int age=8;在初始化块的下面定义,会报错。上面在执行初始化块时系统不是已经为该实例属性赋了一个默认初值0吗?你把age=6;放上面,你认为对吗,你还没有定义即没有声明一个变量显然违反了变量的生成规则,编译器不报错才怪呢,把int age=8;放上面OK,然后要重新给变量age赋值,可以直接age=6;因为变量age已经声明过了,即定义过了,是int类型,无需也不能再重新定义,即int age=6;这样就等于定义了两个一样的变量,编译器同样会报错,不知道你明白了没

#8


up

#9


是的,应该吧int age=8;放在块的上面。

#10


额,对于这一点的话,如果你在age前面加个this就可以编译通过了。
即System.out.println(this.age);
其实这点我也有点疑惑,在没有this关键字前缀的情况下编译器报出的错误为不能在其定义前引用,而加了this关键字它就可以通过编译了。
而且前输出为0,后输出为6。
我想跟编译器处理上有关,如果你不加this关键字,编译器无法识别在age定义之前到底为成员变量还是局部变量。