代码
package ydZh;class J_SuperClass
{
void mb_method(){
System.out.println("J_SuperClass::mb_method");
}
void mb_fun(){
System.out.println("J_SuperClass::mb_fun");
this.mb_method();
}}
class J_SubClass extends J_SuperClass
{
void mb_method(){
System.out.println("J_SubClass::mb_method: Begin");
super.mb_fun();
System.out.println("J_SubClass::mb_method: End");
}
}
public class J_Test
{ public static void main(String[] args)
{
J_SubClass a = new J_SubClass();
a.mb_method();
}
}
第一次发帖,不知道有什么规矩,多多包涵!!!!
package ydZh;class J_SuperClass
{
void mb_method(){
System.out.println("J_SuperClass::mb_method");
}
void mb_fun(){
System.out.println("J_SuperClass::mb_fun");
this.mb_method();
}}
class J_SubClass extends J_SuperClass
{
void mb_method(){
System.out.println("J_SubClass::mb_method: Begin");
super.mb_fun();
System.out.println("J_SubClass::mb_method: End");
}
}
public class J_Test
{ public static void main(String[] args)
{
J_SubClass a = new J_SubClass();
a.mb_method();
}
}
第一次发帖,不知道有什么规矩,多多包涵!!!!
如果不加super,那么执行的就是子类的mb_fun();方法。
弄清这个,你在理一遍,应该就明白了。
程序首先初始化了类J_Test,然后调用了里面的main方法,通过指令new在堆中创建了一个J_SubClass类型
的对象,并初始化为默认值,并把这个对象的引用压入main方法的操作数栈,在存到main方便的局部变量
表中的索引0处。然后是调用方便mb_method(),用的字节码指令是invokevirtual(这个指令会按照引用的
对象的实际类型来调用方法),在调用之前把对象的引用从局部变更中取出,压入到mb_method()方便的操
作数栈,在到这个方法的局部变量表的索引0,在调用这个方法时选打印出了“J_subclass::mb_method:Begin"
字符串,然后是对过super关键字调用了父类的方法,这个时候调用方法用到的字节码指令是invokespecial。
这个指令会按照对象的引用类型调用方法,调用方法mb_fun()之前会把对象的引用压入到此方法的操作数栈,但是引时的引用类型是J_superclass,这个是通过对象引用找到的。所以super.mb_fun()方法会去调用类J_superClass中的mb_fun()方法,然后打出了字符串“J_sperclass::mb_fun",然后在这个方法中又调用了
this.mb_method(),其实这个this不用写,他指的就是方法mb_method()局部变量表索引0处的对象引用,关于你和程序为什么
会是个无限循环,关键的原因就是在这里,因为调用mb_method()方法的字节码指令是invokevirtual,
而在方法mb_method()局部变量表中对象的引用类型是J_superclass,
但是这个对象的实际类型是J_subclass,所以用invokevirtual调用的mb_method()
指向了J_subclass中的mb_method(),接下去就不用我说了,一个无限循环。