多态在JVM中的实现——invokevirtual与invokespecial

/*

 *http://blog.csdn.net/qc_liu

 */


先给一段程序

public class ChildClass extends BaseClass{

	public static void main(String[] args) {
		BaseClass bc = new ChildClass();
		bc.print();
		bc.baseMethod();

	}

	void print()
	{
		System.out.println("print_ChildClass");
	}
	
	void childMethod()
	{
		System.out.println("childMethod");
	}

}



public class BaseClass {
	private void priMethod()
	{
		System.out.println("BaseClass scret");
	}
	
	
	void print()
	{
		System.out.println("print_BaseClass");
	}
	
	void baseMethod()
	{
		this.print();
		this.priMethod();
	}

}


BaseClass base = new ChildClass()这一句用一个基类的引用,指向了一个子类的对象。大名鼎鼎的多态??疑问


      这么做会使base只能调用基类的方法,但是如果ChildClass中override了基类中的方法,则调用的就是override之后的方法。所以base.print()其实是调用的覆盖后的print(),而baseMethod()则是调用的基类中的方法,并且base不能调用childMethod()方法。

     java这种多态性背后的有什么神秘之处么?一点都没有。解释这个问题还要从虚拟机的实现入手。

       上图!


       这个是类被虚拟机加载进方法区之后,在方法区里面的布局。

       如果我们像上面那样,用一个基类引用指向子类对象,那么,这个引用所绑定的类还是子类。只不过它所能访问的虚方法表与一般子类对象不同。上面黄色的部分才是base这个引用所能访问的vtable的范围(关于vtable的生成有时间在总结),而普通的子类引用可以访问整个子类的vtable。所以能很明显的看到,红色的两个方法才是它真正可以调用的。

       有一点需要注意的是,上述代码中的base就是一个指向子类的引用!因此,这段程序测试的结果是



 

      可以看到,this在基类中已经不再代表BaseClass的对象,因为调用时进入虚拟机栈的是一个子类的引用。所以this.print()会调用子类的print()。

     强调一下this的含义:代表着调用本方法的类实例的引用。

      但是!!!问题来了!!!为神马this.priMethod()可以调用基类的私有方法呢?偷笑有没有一种被骗了的感觉呢?这里需要再说明一下,这个this就是一个子类对象的引用,一点没错。但在这里,子类对象的引用就可以调用其基类的私有方法,原因是,这里的调用不再是invokevirtual,而变成了invokespecial!

      这里,就必须要大体解释一下这个invokespecial是个什么东西。它的作用是调用实例初始化方法,私有方法,父类的方法(详情可以参考JVM规范)。这里我们调用的是父类的私有方法,这里这个父类当然是针对上下文环境里这个this而言的。所以,编译器产生了invokespecial指令,使得在这里用子类的对象的引用调用了父类的方法。

      至于编译器为什么这么任性的做了这样的工作,可能是规范需要,可能是自动的优化,暂时未知……



EOF

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值