public static void main (String[] args){
A a = new A(5); //1.new A的对象
}
}作者: 谢毅 时间: 2013-1-21 21:02
A a到这里的时候发生了什么?子类A被分析成字节码放到了虚拟机,接着父类B也被分析成字节码放到了虚拟机,然后虚拟机检测子类与父类的依赖程度,也就是有无重写。
new A(5)这里又发生了什么?虚拟机中的字节码生成子类的默认构造函数对象接着实例对象newInstace(),由于不管子类有无重写,子类与父类有基本的依赖,所以在newInstance()前会先调用父类的构造函数,这里一般为隐式(super()),这个super则是虚拟机通过子类的字节码对象getSuperClass()找到的,所以父类的构造函数执行到draw()的时候通过先前的检测这里就调用了子类的draw(),子类的draw()执行到radius的时候子类这时还没进行newInstance(),所以为默认值0
A a = new A(5)用个模糊流程来模拟下:
Class.forName("A");//只是描述了内存中的状态
Class.forName("B");//同上
Constructor c1 = Class.forName("A").getConstructor(int.class);
c1.newInstance(5);//这里我猜虚拟机在这里打了个标记,暂不执行,紧接着执行下面的代码
Class clazz = Class.forName("A").getSuperClass();
Constructor c2 = clazz.getConstructor();
c2.newInstance();//这里执行完后虚拟机就返回刚才的标记那里继续执行
作者: 高浩 时间: 2013-1-21 22:04
class B{
private int radius = 10; 存在了继承关系,如果调用子类构造函数,顺序是这样
public void draw(){ 子类里面有一条隐式的父类构造函数会先调用它,而B类
System.out.println("B.draw,radius = "+radius); 虽是父类,但他也有父类的,他里面也有一条隐式的父
} 类构造函数,用来给自己初始化。他的父类则是Object
public B(){ 然而在次之前,还没有int radius=10;而是默认值0
super(); //这里调用了Object的构造函数 所以结果会是那样。
System.out.println("B constructor");
draw();这里为什么调用的是子类的draw()而不是父类的?
}
}
public class A extends B{
private int radius = 1;
public void draw(){
System.out.println("A.draw(),radius = "+radius);
}
public A(int radius){
super(); //这里调用了B类的构造函数
this.radius = radius;
System.out.println("A contructor");
}
public static void main (String[] args){
A a = new A(5);
}
}