在java编程思想这本书中有一小节讲:构造器内部的多态方法行为,源码如下:class Glyph{
void draw(){syste.out.println("Glyph.draw()");
Glyph(){ system.out.println("Glyph() before draw()");
draw();
system.out.println("Glyph() after draw()");
}
}class RoundGlyph extends Glyph { private int radius = 1;
RoundGlyph(int r){ radius = r;
system.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
} void draw(){ system.out.println("RoundGlyph.draw(), radius = " + radius);
}}
public class RolyConstructors {
public static void main(string[] args){
new RoundGlyph(5);
}
}
输出的结果如下:
Glyph() after draw()
RoundGlyph.draw(), radius = 0;
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5在类Glyph的构造函数中调用了一个draw()方法,这个方法的调用最终是指向了子类RoundGlyph中的draw()方法,调用这个方法用的字节码指令为invokevirtual,在<深入理解java虚拟机>(周志明)这本书中写到了多态的本质是invokevirtual调用的方法在运行时会找到操作数栈的第一元素所指的实际类型.那么在本段代码中,类Glyph的构造函数中调用draw()方法的时候,是怎么指向RoundGlyph类的?,操作数栈顶第一个元素指是什么?我只知道在局部变更表的第一个元素是this.
这个问题想了两天了,一直是不得其解,希望高人指点迷经.
多态虚拟机java栈class
void draw(){syste.out.println("Glyph.draw()");
Glyph(){ system.out.println("Glyph() before draw()");
draw();
system.out.println("Glyph() after draw()");
}
}class RoundGlyph extends Glyph { private int radius = 1;
RoundGlyph(int r){ radius = r;
system.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
} void draw(){ system.out.println("RoundGlyph.draw(), radius = " + radius);
}}
public class RolyConstructors {
public static void main(string[] args){
new RoundGlyph(5);
}
}
输出的结果如下:
Glyph() after draw()
RoundGlyph.draw(), radius = 0;
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5在类Glyph的构造函数中调用了一个draw()方法,这个方法的调用最终是指向了子类RoundGlyph中的draw()方法,调用这个方法用的字节码指令为invokevirtual,在<深入理解java虚拟机>(周志明)这本书中写到了多态的本质是invokevirtual调用的方法在运行时会找到操作数栈的第一元素所指的实际类型.那么在本段代码中,类Glyph的构造函数中调用draw()方法的时候,是怎么指向RoundGlyph类的?,操作数栈顶第一个元素指是什么?我只知道在局部变更表的第一个元素是this.
这个问题想了两天了,一直是不得其解,希望高人指点迷经.
多态虚拟机java栈class
解决方案 »
- java 串口通信 数据格式问题
- jdbc连oracle在eclipse中没报错,但没有显示查询???
- 初学者,有一小段代码让大家给指点下!
- 200分,求助关于窗口的,参与就给分 :)
- 用JCreater新建JAVA文件时的问题!!
- 帮我调整里面的程序,为什么界面那么难看
- 安装了EDITPLUS和JCREAT,还都必须再装上JDK吗?如果那样的话我还是直接用JB好了。
- 怎么实现 JFrame 的“On Top”
- Socket通讯中建立多个数据通道!
- rs.getInt(1)为什么不行呢?
- 请问在JAVA中我用BigDecimal来计算百分比,百分比之和不等于100%
- 用java.net去post一个请求,但是返回的数据太大,如何完整接受?
class Glyph{
void draw(){syste.out.println("Glyph.draw()");
Glyph(){
system.out.println("Glyph() before draw()");
draw();
system.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
private int radius = 1;
RoundGlyph(int r){
super() // compiler 自动加载call父类的构造器
radius = r;
system.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
}
void draw(){
super.draw() // 调用父类的draw()方法
system.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class RolyConstructors {
public static void main(string[] args){
new RoundGlyph(5);
}
}
因为 draw() 方法被overridden, 所以会调用子类的draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGLyph(), radius = 5首先运行结果是上面的这个……
new RoundGlyph(5);
1.这段代码运行时会先访问其父类 Glyph的构造函数:
System.out.println("Glyph() before draw()"); 打印输出
2.然后draw();会执行被子类RoundGlyph覆写的draw()方法
此时radius还没有被赋初值,默认为0,因此打印出 RoundGlyph.draw(), radius = 0
3.继续执行之后的System.out.println("Glyph() after draw()"); 打印输出
4.父类的构造函数结束,执行本类RoundGlyph的构造函数
radius = r;
System.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
给radius赋值5,后输出程序流程是这样的,要上升到栈啊、堆啊的就要等大神回复你了
也就是java多态的实现原理?嗯,我找了篇文章,你看下
http://www.cnblogs.com/stonehat/archive/2012/04/30/2476798.html或者你也可以再百度下“java多态原理”,只能帮你到这里了
void draw(){System.out.println("Glyph.draw()");}
Glyph(){
System.out.println("Glyph() before draw()");
System.out.println(this.getClass()); //1111111
this.draw(); //2222222 加了this
System.out.println("Glyph() after draw()");
}
}class RoundGlyph extends Glyph { private int radius = 1;
RoundGlyph(int r){
radius = r;
System.out.println("RoundGlyph.RoundGLyph(), radius = " + radius);
} void draw(){ System.out.println("RoundGlyph.draw(), radius = " + radius);
}}public class RolyConstructors {
public static void main(String[] args){
new RoundGlyph(5);
System.out.println("-------------------------");//333333
new Glyph(); //444444
}
}
加了4行代码,楼主运行一下就知道咯
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。
这里面有个问题,子类并没有被实例化
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗??
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗??
不是我搞笑,在调用父类构造函数的时候,还没有调用子类的构造函数。
子类在被实例化的时候首先调用父类的构造方法,你说的是对的;
而这个this为什么指向子类,很简单啊,this代表的是对象实例,在你的代码中Glyph类没有被实例化,仅仅是它的子类被实例化了,所以this才指向roundGlyph类的对象啊。
你看看我加的第4行代码,创建Glyph类对象的运行结果,this不就指向他自己了吗。
这里面有个问题,子类并没有被实例化
子类没有实例化,你在搞笑吗??
我理解有点问题了,应该是在堆里已分配了空间,初始化成了默认值。