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 //这里,为什么是0而不是10?
30
40
Press any key to continue...这个程序是怎样执行的?
{
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 //这里,为什么是0而不是10?
30
40
Press any key to continue...这个程序是怎样执行的?
Test4()
{
print();
在调父类print()方法时因为子类从重了此方法,所以又会去调子类的
void print()
{
System.out.println(i);因为这个时候i只在父类中=10并没有在子类中被赋值所以第一次打印是0;
}
继续运行父类构造函数i=20;
运行完父类构造函数会去运行子类的i=30;再运行字类构造函数
Test3()
{
print();
再次调用子类print()方法打印出30;
i=40;
}
最后执行完整的System.out.println(new Test3().i);打印出40我的理解是这样
即使产生一个Test4对象,第一行输出的还是0。
因为JAVA编译器保证所有变量在函数被调用前必须被初始化,
即使你在变量定义处给定了初始值,对于int来说,它还是会被赋初始值0试着将
Test3()
{
print();
i=40;
}
改为
Test3()
{
super.print();
i=40;
}
看看结果是什么!
在new Test3()时候,确实会先调父类的构造函数
但这不是重点,重点是
JAVA编译器保证所有变量在函数被调用前必须被初始化
任何一个类都会有一个默认的执行方法 <init> 也就是构造方法,上边Test3调用构造方法时同时也调用Test4的默认构造方法。其次:非静态成员变量在默认构造时(初始化),会被赋予默认值,也就是说 实际上是调用了Test4的构造方法,但这个构造方法是一个副0值得构造方法 <init>。最后:代码的执行顺序 1 -> 运行程序 执行 Test3的 main方法
System.out.println(new Test3().i);
2 -> 构造Test3的匿名对象 调用 Test3的构造方法
Test3的构造方法首先执行父类Test4的默认构造方法 所有成员对象值为 0 或者 空 null
3 -> 继续执行Test3的构造方法
public class Test3
extends Test4 {
int i = 30;
Test3() { System.out.println(i);
print();
System.out.println("33333333333333");
i = 40;
} public static void main(String[] args) {
System.out.println(new Test3().i);
System.out.println("111111111111111");
} void print() {
System.out.println("222222222222222");
System.out.println(i);
}
}class Test4 {
int i = 10;
Test4() {
System.out.println(i);
System.out.println("44444444444444");
print();
System.out.println("55555555555555");
i = 20;
System.out.println(i);
} void print() {
System.out.println("6666666666666");
System.out.println(i);
}
}
下面是输出的结果:
10444444444444442222222222222220555555555555552030222222222222222303333333333333340111111111111111
从以上的结果不难看出程序运行的先后,和i值的变化,不用我说一看就明白