/*
对于类中对成员变量的初始化和代码块中的代码全部都挪到了构造函数中,
并且是按照java源文件的初始化顺序依次对成员变量进行初始化的,而原构造函数中的代码则移到了构造函数的最后执行
*/
import static java.lang.System.out; public class PersonDemo
{
public static void main(String[] args)
{
//*********测试父类与子类之间的循环调用的问题
out.println("main1"); Father f = new Father(); out.println("main2"); f.show(); out.println("main3"); //*********测试两个无关类的循环调用的问题 MyClass11 m1=new MyClass11();
m1.myOut();
}
} class Father
{
public Son s ; //=new Son(); /*
public Song s= new Son(), 注意在这里进行初始化操作相当于在构造函数中进行初始化,会导致栈溢出, why?
在主函数中我们产生了一个Father对象, 然后在new一个Son对象的过程中,Son对象调用其父类的构造方法来完成
一些子类中包含父类成员的初始化,最终导致了循环调用,最终栈溢出
*/
public newSon ns =null; // new newSon(); public Father()
{
this(10);
System.out.println("Father");
} public Father(int a)
{
//this();很显然, 加上这一句就会形成构造函数递归调用!哈哈。。。
} public void show()
{
s = new Son();
/*
如果我们将 s 的赋值操作放在这里, 也就是去掉 public Son s = new Son()的初始化,这样就不会导致栈溢出了
看一看也就会明白了, new Son()时会调用父类Father的构造方法来完成Son的一些成员的初始化,但是其父类构造
函数中没有行循环调用!
*/
ns = new newSon(); System.out.println("father show"); s.show();
ns.show();
} public class newSon extends Father//内部类同样会导致上面的问题!
{
public newSon()
{
System.out.println("newSon");
} public void show()
{
System.out.println("newSon show");
}
}
} class Son extends Father
{
public int a = 20; public Son()
{
super();
System.out.println("Son");
} public void show()
{
System.out.println("Son show");
}
} class MyClass11{ MyClass22 m2;
//MyClass22 m2=new MyClass22();//这样写会导致循环调用问题 public MyClass11(){
//m2=new MyClass22();//这样写和上面的错误是一样的
}
public void show(){
System.out.println("This MyClass11");
}
public void myOut(){
m2=new MyClass22();//m2的赋值放在这里
m2.show();
}
} class MyClass22{ MyClass11 m1;
public MyClass22(){
m1=new MyClass11();//移位main()函数中没有定义MyClass22的对象,所以这句赋值不会导致循环调用的问题,只需要将MyClass11中的赋值操作更改一下就好了
}
public void show(){
System.out.println("This MyClass22");
}
public void myOut(){
m1.show();
}
}