class Sup{
private int i=2;
public Sup(){
this.foo();
}
public void foo(){
System.out.println(i);
}
}
public class test1 extends Sup{
private int i=22;
public test1(){
//System.out.println("hello");
i=222;
}
public void foo(){
System.out.println(i);
}
public static void main(String args[]){
new test1();
//
}
}
没人理我&……哎,我发帖我!!这个输出为什么是0???
private int i=2;
public Sup(){
this.foo();
}
public void foo(){
System.out.println(i);
}
}
public class test1 extends Sup{
private int i=22;
public test1(){
//System.out.println("hello");
i=222;
}
public void foo(){
System.out.println(i);
}
public static void main(String args[]){
new test1();
//
}
}
没人理我&……哎,我发帖我!!这个输出为什么是0???
子类的构造函数会默认首先调用父类的同名构造函数
因此,在test1()构造时会先super();
而父类的构造函数中有这样的语句:this.foo();
意义是调用当前引用的foo方法
当前引用正是new出来的test1的一个对象
实际上调用的是test1中的foo方法
而在子类执行完父类的构造方法之前,是不会进行自身的构造的
而test1中的i这个时候还没有初始化
所以出现了这种情况
其执行顺序是在test1的构造方法中调用Sup的构造方法->初始化Sup的i->this.foo();(这句代码执行的时候调用的是test1的foo方法,就是多态,此时test1的i还没有显示初始化,其默认为0,所以打印为0)->初始化test1的i(此时test1的i为22)->执行test1的构造方法(此时test1的i为222)。
然后现在Sub()构造方法其实调用的是test1类中的foo()方法,为什么会是这样呢?
因为用了this这个关键字,而这个关键字是表示现在正在初始化的那个类,也就是test1类中的foo方法
现在,会发现这个类是要覆盖父类的方法,也System.out.println(i);
而问题就在这里了,这个i是哪里的i,答案是test1中的i,而这个i的初始值是0
为什么是0呢,必须知道的是
只有在一个类初始化(也就是构造方法完成)完成之后才会对普通类型的进行初始化(也就是赋值222)
而对于类变量(static类型的)会在初始化(也就是构造方法完成)之前赋值,所以可以看到这里的i显然还没有赋值222 因为还没有初始化完成呢
所以就输出了0 了不知道这么说你懂不懂了
这个程序是要绕很多弯子 其实正是这样的题才勾起了我学java的兴趣
以前一直觉得java简单 学多了就觉得不那么简单 特别是关于内存 关于地址
要是深挖的话不比C语言简单。。
而你父类的构造方法是this.foo();
这个this是你子类的实例,所以他调用的不是父类Sup里的foo()方法而是子类里的foo()方法
此时子类的构造方法没执行(没初始化),所以输出的i是0;
本来就是啦, 在那边吼了一下,没人理我,不得已贴出来了,嘻嘻 private int i=22;
public test1(){ }这当中的i不起作用吗??在前面加个private static int i=22;结果就显示22了呀。
改成private static int i = 22;
运行结果就是22了
this.foo();
}
这个方法调用的是子类Text1中的
public void foo() {
System.out.println(i);
}方法