啊!Java虚方法
什么是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虚方法的更多相关文章
- java 虚方法。 后面new 那个类, 就调用哪个类的方法 ,而非定义类的方案。 关于父子 类的 呵呵
java 虚方法. 后面new 那个类, 就调用哪个类的方法 ,而非定义类的方案. 关于父子 类的 呵呵 在多态的情况下,声明为父类类型的引用变量只能调用父类中的方法,但如果此变量 ...
- Java的虚方法
虚方法出现在Java的多态特性中, 父类与子类之间的多态性,对父类的函数进行重新定义.如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding).在Java中,子类 ...
- 为何JAVA虚函数(虚方法)会造成父类可以"访问"子类的假象?
首先,来看一个简单的JAVA类,Base. 1 public class Base { 2 String str = "Base string"; 3 protected vo ...
- C#虚方法virtual详解
转: http://www.cnblogs.com/jason_yjau/archive/2009/08/25/1553949.html C#虚方法virtual详解 在C++.Java等众多OOP语 ...
- C++中的纯虚方法
在学习数据结构中优先级队列时遇到纯虚方法的定义,一时没想起来,便查了一下. 1.纯虚方法解决什么样的问题,为什么要设计出纯虚方法? 考虑下面的需求,基类声明了一个方法,这个方法只针对具体的子类才有意义 ...
- 4.C#虚方法virtual详解
C#虚方法virtual详解 在C++.Java等众多OOP语言里都可以看到virtual的身影,而C#作为一个完全面向对象的语言当然也不例外. 虚拟函数从C#的程序编译的角度来看,它和其它一般的函数 ...
- C++ 纯虚方法
1.纯虚方法解决什么样的问题,为什么要设计出纯虚方法? 考虑下面的需求,基类声明了一个方法,这个方法只针对具体的子类才有意义,比如Animal的Eat()方法,调用Animal的Eat方法是没有意义的 ...
- [翻译] Virtual method interception 虚方法拦截
原文地址:http://blog.barrkel.com/2010/09/virtual-method-interception.html 注:基于本人英文水平,以下翻译只是我自己的理解,如对读者造成 ...
- C#之抽象类、虚方法、重写、接口、密封类
前言 学了这么长时间的C#,我想说对于这个东东还是不是特别了解它,以至于让我频频郁闷.每次敲代码的时候都没有一种随心所欲的感觉.所以不得不在网上搜集一些资料,look 了 look~ 内容 ...
随机推荐
- 应聘阿里,字节跳动美团90%会问到的JVM面试题! 史上最全系列!
Java 内存分配 • 寄存器:程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码.• 静态域:static 定义的静态成员.• 常量池:编译时被确定并保存在 .class 文件中的(f ...
- Java中的主线程
目录 概览 主线程 怎么来控制主线程 主线程和main()函数的关系 主线程中的死锁(单个线程) 概览 前段时间有同事提到了主线程这个名词,但当时我们说的主线程是指Java Web程序中每一个请求进来 ...
- yii\web\Request::cookieValidationKey must be configured with a secret key.
yii\web\Request::cookieValidationKey must be configured with a secret key. 出现的错误表示没有设置 cookieValida ...
- Win10定期执行python程序
一:windows10自带的计划程序 第一步:在 计算器右击 --> 选择管理 进入如下界面: 第二步:选择 系统工具 --> 任务计划程序 ,点击右侧的 "创建基本任务&q ...
- Matlab 数值计算
本博客记录一些简单的计算 det(A):矩阵求行列式 A=[1,2;3,4]; det(A) ans=-2; inv(A):矩阵求逆 A=[1,2;3,4]; B=inv(A) B=[-2,1;1,5 ...
- 再论<? extends T>和<? super T>
参考: https://www.cnblogs.com/drizzlewithwind/p/6100164.html Java 泛型 <? super T> 中 super 怎么 理解?与 ...
- Java集合【2】--iterator接口详解
目录 一.iterator接口介绍 二.为什么需要iterator接口 三.iterator接口相关接口 3.1 ListIterator 3.2 SpitIterator 3.2.1 SpitIte ...
- MySQL的中的全局锁、表级锁、行锁
MySQL的中的全局锁.表级锁.行锁 学习极客时间-林晓彬老师-MySQL实战45讲 学习整理 全局锁 对整个数据库实例加锁.通过使用Flush tables with read lock (FTWR ...
- mark一下2020已经阅读的书单专栏和源码
1.书籍 已经阅读: 深度工作 代码整洁之道 正在阅读: 敏捷软件开发 程序员修炼之道 程序员思维 计划阅读: 人月神话 数据密集型系统设计 如何阅读一本书 卓有成效的管理者 算法 第四版 sprin ...
- SQL注入步骤
1.判断是否存在注入,注入是字符型还是数字型2.猜解SQL查询语句中的字段数3.确定回显的字段数4.获取当前数据库5.获取表中字段名6.下载数据