public class Test3 extends Test4{
int i = 30;
Test3(){
print();
i = 40;
}
public static void main(String[] args){
System.out.println(new Test3().i);
}
void print(){
System.out.println(i);
}
}
class Test4{
int i = 10;
Test4(){
print();
i = 20;
}
void print(){
System.out.println(i);
}
}
结果是
0
30
40为什么
int i = 30;
Test3(){
print();
i = 40;
}
public static void main(String[] args){
System.out.println(new Test3().i);
}
void print(){
System.out.println(i);
}
}
class Test4{
int i = 10;
Test4(){
print();
i = 20;
}
void print(){
System.out.println(i);
}
}
结果是
0
30
40为什么
在new Test3()的执行就解释不了了
方法但执行的是子类的print();方法而不是父类的。因为在子类中i没有被初始化所以i的值为0,然后创建子类的构造方法执行print()方法,因为这时i已经被初始化了所以输出的就是30。最后执行System.out.println(new Test3().i);输出的就是i最后的值40.
期待高手解答,debug了没弄明白
期待高手解答,debug了没弄明白
因为Test3 extends Test4 所以test3中的print()覆盖了父类test4的print()方法,直接执行了print(),但是此时i没有从父类中继承下来,所以初始化初始化默认为0,当new Test3()时候 调用test3的构造函数,执行了print();在此之前i已经被初始化为i=30,所以输出的就是30。最后执行(new Test3().i);此时的i是构造函数里 在构造时候赋值为 i=40,所以只要是 new出来的 test3,其中的i值 就一定是40。。
讲 的就是这个问题
因为Java虚拟机必须确保当Test3操作的时候,对象中的数据是符合Test4对象规范的。
3.Test4的构造函数中调用了Print,因为多态的原因,执行了Test3中的print方法,此时
i尚未进行任何赋值所以输出int的默认值04.Test4构造函数执行完之后,开始执行Test3的字段赋值语句,因为其执行顺序高于构造函数5.执行Test3构造函数
public class Test3 extends Test4{
int i = 30;
Test3(){
print2();
i = 40;
}
public static void main(String[] args){
System.out.println(new Test3().i);
}
void print2(){
System.out.println(i);
}
}
class Test4{
int i = 10;
Test4(){
print();
i = 20;
}
void print(){
System.out.println(i);
}
}结果是
10
30
40
其次,再来说为什么方法不一样就会有不同的结果。这是因为方法相同时有个覆盖的问题,创建的是子类的实例new Test3(),不管中间要经过多少“曲折”,在这个过程中不管你在哪调用,其调用的结果只能是子类的方法(除非你用super).
再次,就是初始化顺序的问题了。父类静态变量->父类静态初始化块->子类静态变量->子类静态初始化块->父类变量->父类初始化块->父类构造器->子类变量->子类初始化块->子类构造器
知道了这些自然就明白了
int i = 30;
Test3(){
print();
i = 40;
}
public static void main(String[] args){
System.out.println(new Test3().i);
}
void print(){
System.out.println("test3 "+i);
}
}
class Test4{
int i = 10;
Test4(){
print();
i = 20;
}
void print(){
System.out.println("test4 "+i);
}
}
我开始也认为是10,30,40看了j2eemail的解释便用上面的代码测试了一下确实执行的是Test3中的print()
{
int i = 20;
public Test2()
{
print();
i = 1111;
}
void print(){
System.out.println("print:" + i);
}
public static void main(String[] args)
{
System.out.println(new Test2().i);
}}为什么这样,输出的值却不是0
1、JVM将类加载到内存。。这个时候所有的类都是以2进制0的形式存在的
2、再慢慢的按照我们知道的初始化我们看这道题
new Test3().i 的时候。。
1、将Test3,Test4初始化成为2进制的0(也就是所有的东西都是0)
2、初始化Test4的变量再调用Test4的构造器调用Print方法,注意由于这里面存在多态。所以调用的是Test3的print的方法。。所以由上面类的初始化过程我们可以看到。Test3是以2进制0的形式存在的(因为还没有被初始化)。所以这个时候调用Print方法,所以i是0(注意是2进制的0)。至于楼主问的第二道题那是因为只有1个类。。类会先初始化类的变量。。然后再初始化构造器。所以这个时候打印i。i已经是被初始化的了。所以我们总结出来:尽量让类平稳的度过构造阶段。不要在构造器内添加一些可能影响逻辑的方法