什么是Java的虚方法呢,我们首先看看什么是虚函数


虚函数

百度百科的解释为:

在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的[成员函数],用法格式为:virtual 函数返回类型 函数名(参数表) {[函数体]};实现[多态性],通过指向派生类的基类[指针]或引用,访问派生类中同名覆盖成员函数。

  从上面解释上我们抓住几个关于虚函数的关键字 基类、派生类、同名覆盖(重写),因此我们可以理解为虚函数其实就是描述我们子类重写的父类方法。

  在虚函数声明定义这块,C++可以通过virtual关键字来进行直接声明,而在Java中,并没有提供我们关键字来声明虚函数,但是我们通过虚函数的定义,我们可以理解为被override的方法都是virtual的。


关于虚方法的调用

在Java语言中,class文件被会解释成机器码,而方法调用会被解释成具体的方法调用指令,大致可以以下五类指令:

指令 描述
invokestatic 调用静态方法
invokespecial 调用实例构造方法,私有方法和父类方法
invokevirtual 调用虚方法
invokeinterface 调用接口方法,在运行时再确定一个实现此接口的对象
invokedynamic 在运行时动态解析出调用点限定符所引用的方法之后,调用该方法;

注意:invokedynamic 指令是jdk1.7才加入的,但是在jdk1.7中并没有开始使用。在jdk1.8中才开始大量使用,主要就是我们大量用的 lambda 表达式。

我们接下来去字节码验证下invokevirtual指令,so! 我们来举个

// 类声明文件如下:
public class VirtualDemo {
public static void main(String[] args) {
Parent obj = new Child();
obj.func();
}
}
class Parent{
public void func(){
System.out.println("parent func");
}
}
class Child extends Parent{
@Override
public void func() {
System.out.println("child func");
}
}

  接下来我们来获取这个类的字节码:

//  dos 命令如下
javac VirtualDemo.java
javap -verbose VirtualDemo

 VirtualDemo部分字节码指令如下:

解释:在字节码第4行,我们可以看到是一个invokespecial指令,代表调用的是调用子类Child的实例构造init方法。在第9行中,我们可以看到是一个invokevirtual指令,表示调用虚方法,并且表示这是父类Parent中的方法func(),但这只是编译时是这样表示,等字节码真正执行的时候会通过方法表去正确找到子类Child中func()方法。

参考链接:

啊!Java虚方法的更多相关文章

  1. java 虚方法。 后面new 那个类, 就调用哪个类的方法 ,而非定义类的方案。 关于父子 类的 呵呵

    java   虚方法.     后面new  那个类, 就调用哪个类的方法 ,而非定义类的方案.  关于父子 类的   呵呵 在多态的情况下,声明为父类类型的引用变量只能调用父类中的方法,但如果此变量 ...

  2. Java的虚方法

    虚方法出现在Java的多态特性中, 父类与子类之间的多态性,对父类的函数进行重新定义.如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding).在Java中,子类 ...

  3. 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?

      首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...

  4. C#虚方法virtual详解

    转: http://www.cnblogs.com/jason_yjau/archive/2009/08/25/1553949.html C#虚方法virtual详解 在C++.Java等众多OOP语 ...

  5. C++中的纯虚方法

    在学习数据结构中优先级队列时遇到纯虚方法的定义,一时没想起来,便查了一下. 1.纯虚方法解决什么样的问题,为什么要设计出纯虚方法? 考虑下面的需求,基类声明了一个方法,这个方法只针对具体的子类才有意义 ...

  6. 4.C#虚方法virtual详解

    C#虚方法virtual详解 在C++.Java等众多OOP语言里都可以看到virtual的身影,而C#作为一个完全面向对象的语言当然也不例外. 虚拟函数从C#的程序编译的角度来看,它和其它一般的函数 ...

  7. C++ 纯虚方法

    1.纯虚方法解决什么样的问题,为什么要设计出纯虚方法? 考虑下面的需求,基类声明了一个方法,这个方法只针对具体的子类才有意义,比如Animal的Eat()方法,调用Animal的Eat方法是没有意义的 ...

  8. [翻译] Virtual method interception 虚方法拦截

    原文地址:http://blog.barrkel.com/2010/09/virtual-method-interception.html 注:基于本人英文水平,以下翻译只是我自己的理解,如对读者造成 ...

  9. C#之抽象类、虚方法、重写、接口、密封类

    前言    学了这么长时间的C#,我想说对于这个东东还是不是特别了解它,以至于让我频频郁闷.每次敲代码的时候都没有一种随心所欲的感觉.所以不得不在网上搜集一些资料,look 了 look~ 内容   ...

随机推荐

  1. 还不懂Java高并发的,建议看看这篇阿里大佬的总结,写的非常详细

    前言 进程是计算机中程序关于某几何数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位.是操作系统结构的基础 线程可以说是轻量级的进程,是程序执行的最小单位,使用多线程而不用多进程去进行并发程 ...

  2. Ayoa:麻雀虽小、五脏俱全的思维导图工具

    Ayoa是一款简单好用的思维导图软件,在PC端可以使用Ayoa网页版,也就是不用下载即可使用,十分轻便省力.但麻雀虽小,五脏可十分俱全,同类的其他大型软件有的东西它可一点不少,甚至还有更多的特殊功能. ...

  3. PowerPoint无法正常加载MathType的解决方法

    MathType是一款十分便捷的数学公式编辑器,可以和很多办公软件和网站兼容使用,我们日常用的比较多的也就是Office和WPS,更具体的说是Word\Excel\PPT等等一系列办公常用软件. 不过 ...

  4. FL studio系列教程(十八):FL Studio输出监视面板讲解

    在FL Studio编曲制作软件中输出监视器面板主要的功能是监视输出电平和波形以及频谱.下面大家就跟小编一起来认识下什么是FL Studio监视面板以及它的一些特征吧! 1.首先,我们来看一下输出监视 ...

  5. 学习netty遇到的关于 LineBasedFrameDecoder 的问题

    最近在看<Netty权威指南>这本书,关于TCP粘包/拆包,书中使用的是 LineBasedFrameDecoder 来解决的,但是我在实践的过程中出现了问题,上代码吧. 这个是 serv ...

  6. P6823 「EZEC-4」zrmpaul Loves Array

    发现进行一次排序后先前的操作都无效了,所以只需做最后一次排序后的操作.翻转操作打个翻转标记,互换操作根据翻转标记即可. 时间复杂度 \(O\left(n+m\right)\). code: #incl ...

  7. C语言讲义——传值、传引用

    传值 值类型在做参数的时候,函数内使用的是实参的副本. 函数执行完毕后,即使函数内对参数做了修改,调用方的参数还是原来的值. #include <stdio.h> // 值调用 void ...

  8. 语法解析器续:case..when..语法解析计算

    之前写过一篇博客,是关于如何解析类似sql之类的解析器实现参考:https://www.cnblogs.com/yougewe/p/13774289.html 之前的解析器,更多的是是做语言的翻译转换 ...

  9. kafka入门之broker--日志存储设计

    kafaka并不是直接将原省消息写入日志文件的,相反,它会将消息和一些必要的元数据信息大宝在一起封装成一个record写入日志.其实就是我们之前介绍的batch 具体对每个日志而言,kafka又将其进 ...

  10. LeetCode 035 Search Insert Position

    题目要求:Search Insert Position Given a sorted array and a target value, return the index if the target ...