什么是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. 微软开源的 AI 工具,让旧照片焕发新生

    原文地址:Bringing Old Photos Back to Life 原文作者:Ziyu Wan 译者 & 校正:HelloGitHub-小鱼干 & 鸭鸭 写在前面 在 GitH ...

  2. 如何制作C语言基本数据类型的思维导图

    在使用C语言编写程序时,数据类型是一个非常重要的内容,任何一个不被重视的数据错误都会使编译器无法翻译,导致程序报错. 使用思维导图来梳理各个数据类型是一个很有效的记忆方法,接下来就为大家展示一下我用i ...

  3. ntfs和fat32的区别

    ntfs和fat32是两种不同的磁盘文件系统格式,虽然他们有一定的相似点,但还是具有很大的差异.今天,小编就带大家了解一下ntfs和fat32的区别. 图1 :u盘 一.分区容量 fat32能够有效管 ...

  4. CSP2020 游记

    Day -28 后天就初赛了,考了一套模拟题,自闭,心态爆炸,感觉退役不远了 Day -26(初赛) 香农是谁??? 手写随机nth_element与O(n)的哈希表??? 阅读程序T2时间复杂度分析 ...

  5. Educational Codeforces Round 92 (Rated for Div. 2) B、C题解

    TAT 第一场codeforces B. Array Walk #暴力 #贪心 题目链接 题意 有\(a1, a2, ..., an\) 个格子(每个格子有各自分数),最初为1号格(初始分数为\(a1 ...

  6. C++基础知识篇:C++ 变量作用域

    作用域是程序的一个区域,一般来说有三个地方可以定义变量: 在函数或一个代码块内部声明的变量,称为局部变量. 在函数参数的定义中声明的变量,称为形式参数. 在所有函数外部声明的变量,称为全局变量. 我们 ...

  7. java类,函数传参

    1 package 传参练习; 2 //学生姓名组成的数组:指定区间和查找的名字返回此人是否存在(如果存在返回位置否则-1) 3 public class test1 { 4 public stati ...

  8. 什么,kafka能够从follower副本读数据了 —kafka新功能介绍

    最近看了kafka2.4新版本的一些功能特性,不得不说,在kafka2.0以后,kafka自身就比较少推出一些新的feature了,基本都是一些修修补补的东西.倒是kafka connect和kafk ...

  9. c++11-17 模板核心知识(十二)—— 模板的模板参数 Template Template Parameters

    概念 举例 模板的模板参数的参数匹配 Template Template Argument Matching 解决办法一 解决办法二 概念 一个模板的参数是模板类型. 举例 在c++11-17 模板核 ...

  10. vue+element ctrl+s保存写法

    <el-input type="textarea" ref="inppp" v-model="values" placeholder= ...