问题描述:一个父类,里面包涵一个非静态内部类。在父类的成员变量中,存在对内部类的引用并显式地实例化。当实例化父类的时候,会先实例化父类的成员变量,然后在执行构造方法里面的语句。
当先实例化内部类的时候,就会调用构造方法,虽然我们看起来是无参构造方法,实际上是传进父类对象的有参构造方法,这个是java编译时自动附加的。
好了,就是说要先实例化非静态内部类,必须依赖父类的对象。
下面有个例子:
1 class A{ 2 3 private B b = new B(this); 4 5 public A(){ 6 System.out.println("instance A"); 7 8 } 9 10 public void print(){ 11 System.out.println("invoke A"); 12 } 13 14 private class B{ 15 16 public B(A a){ 17 a.print(); 18 System.out.println("instance B "); 19 } 20 21 }
1 class Test{ 2 public static void main(String[] args){ 3 new A(); 4 } 5 }
根据类、内部类实例化的顺序,可以猜测打印的结果是:
instance A
invoke A
instance B
但是实际上运行结果不是这样,而是:
invoke A
instance B
instance A
为什么呢?为什么不先实例化A的对象,换一句话说,为什么不先执行A的无参构造方法呢?
求大师指点....
字段 成员先初始化。
那请问一下,实例化内部类B的时候,A的对象是怎么来的?
@小白~!:
你不是传了this 吗? this 就是A对象,当前对象, 那为什么 在构造函数中也可以 直接使用this呢?这就是 this的作用
@Qlin: 但是你还没有解释清楚A的this是实例化B之前还是之后才出现的?因为我知道实例化非静态内部类,必须先存在外部类的对象,但是外部类的成员变量有此内部类的实例,这个内部类的实例是依靠谁来生成的?
@小白~!:
晕,this 是当前对象, this是从这个对象开始创建,到创建结束,整个过程的一个指针。
new A()//做了什么
1.先 字段,初始化 new B(this) ,//这时候 的this 还在构建当中,至于 this.print,那你又要了解 方法表是先于对象的。
2.最后才是 A的构造函数,这才是对象初始化完成。
@Qlin:
哦哦,谢谢你,我开始有点明白了,原来类中的方法和对象的实例化是两回事,最少存储空间是在不同区域的。
那么,就是不提倡在类的成员变量里实例化对本类引用的类咯。是吧?
package Test2; class A { private B b = new B(this); // 1 public A() { System.out.println("instance A"); // 4 } public void print() { System.out.println("invoke A"); // 2 - 2 } private class B { public B(A a) { a.print(); // 2 - 1 System.out.println("instance B "); // 3 } } } public class Test { public static void main(String[] args) { new A(); } }
我帮你写出了具体的调用步骤,你可以看下,希望对你有帮助。