方法重载与invokevirtual字节码指令的关系
1、方法重载
创建MyTest5类
public class MyTest5 {
public void test(Grandpa grandpa){
System.out.println("grandpa");
}
public void test(Father father){
System.out.println("father");
}
public void test(Son son){
System.out.println("son");
}
public static void main(String[] args) {
Grandpa g1 = new Father();
Grandpa g2 = new Son();
MyTest5 myTest5 = new MyTest5();
myTest5.test(g1);
myTest5.test(g2);
}
}
class Grandpa{
}
class Father extends Grandpa{
}
class Son extends Father{
}
输出结果如下:

2、方法的静态分派
Grandpa g1 = new Father();
以上代码,g1的静态类型是Grandpa,而g1的实际类型(真正的指向的类型)是Father
我们可以得出这样一个结论:变量的静态类型是不会发生变化的,而实际类型则可以发生变化的(多态的一种体现),实际类型是在运行期方可确定。
方法重载,是一种静态的行为,编译期就可以完全确定。
所以MyTest5最终的输出结果两个都是grandpa
使用jclasslib,调用两个test方法,使用的都是invokevirtual指令

3、方法的动态分派机制
创建MyTest6.java类
package com.example.jvm.bytecode;
public class MyTest6 {
public static void main(String[] args) {
Fruit apple = new Apple();
Fruit orange = new Orange();
apple.test();
orange.test();
apple = new Orange();
apple.test();
}
}
class Fruit{
public void test(){
System.out.println("Fruit");
}
}
class Apple extends Fruit{
@Override
public void test() {
System.out.println("Apple");
}
}
class Orange extends Fruit{
@Override
public void test() {
System.out.println("orange");
}
}
输出结果如下:
Apple
orange
orange
使用jclasslib查看字节码

可以看到apple.test() 对应的指令为 invokevirtual #6 <com/example/jvm/bytecode/Fruit.test> 在编译的时候使用的类型为Fruit,并不知道真正的类型为Apple
方法的动态分派
方法的动态分派涉及到一个重要概念: 方法接收者。
invokevirtual字节码指令的多态查找流程(执行期)
1、找到操作数栈顶的第一个元素,它所指向对象的实际类型
2、在实际对象中找对应的方法(test()方法),检查访问类型是否可以访问,找到了就调用。如果没找到,继续往上找。
比较方法重载(overload)与方法重写(overwrite),我们可以得到这样的结论
方法重载是静态的,是编译器行为; 方法重写是动态的,是运行期行为。
方法重载与invokevirtual字节码指令的关系的更多相关文章
- 第34篇-解析invokeinterface字节码指令
与invokevirtual指令类似,当没有对目标方法进行解析时,需要调用LinkResolver::resolve_invoke()函数进行解析,这个函数会调用其它一些函数完成方法的解析,如下图所示 ...
- Java方法调用的字节码指令学习
Java1.8环境下,我们在编写程序时会进行各种方法调用,虚拟机在执行这些调用的时候会用到不同的字节码指令,共有如下五种: invokespecial:调用私有实例方法: invokestatic:调 ...
- 【synchronized锁】通过synchronized锁 反编译查看字节码指令分析synchronized关键字修饰方法与代码块的区别
前提: 首先要铺垫几个前置的知识: Java中的锁如sychronize锁是对象锁,Java对象头中具有标识位,当对象锁升级为重量级锁时,重量级锁的标识位会指向监视器monitor, 而每个Java对 ...
- jvm理论-字节码指令
Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...
- 大话+图说:Java字节码指令——只为让你懂
前言 随着Java开发技术不断被推到新的高度,对于Java程序员来讲越来越需要具备对更深入的基础性技术的理解,比如Java字节码指令.不然,可能很难深入理解一些时下的新框架.新技术,盲目一味追新也会越 ...
- 从字节码指令看重写在JVM中的实现
Java是解释执行的.包含动态链接的特性.都给解析或执行期间提供了非常多灵活扩展的空间.面向对象语言的继承.封装和多态的特性,在JVM中是怎样进行编译.解析,以及通过字节码指令怎样确定方法调用的版本号 ...
- invokedynamic字节码指令
1. 方法引用和invokedynamic invokedynamic是jvm指令集里面最复杂的一条.本文将从高观点的角度下分析invokedynamic指令是如何实现方法引用(Method refe ...
- [四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式
前言简介 前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是 ...
- 深入理解java虚拟机(六)字节码指令简介
Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...
随机推荐
- redis被攻击,怎么预防
今天,自己的redis服务器被黑客攻击了,数据全部被删除 从图中可以看到,在db0中多了一个crackit,他就是罪魁祸首,他的值就是ssh无密码连接时需要的authorized_keys. 我们被攻 ...
- Kali下进行局域网断网攻击
今天我就来演示一下在kali下的局域网断网攻击,即ARP地址欺骗,下图所要用到的arp地址欺骗状态图: 则: 第一步:假设主机A访问某网站,那么要告知某网站我的IP和MAC地址,但这是以广播的方式告知 ...
- cesium-print 动态打印插件
Cesium 动态打印插件 cesium-print is a plugin for cesium printing Usage Include it in your code after impor ...
- 一个自己编写的简单AC自动机代码-----AC automata get √
最近一直在优化项目中字符串匹配的问题,于是就想起了自动机,之前也看过一些文章,一直没有实现,现在项目中要用,然后又看了一些关于AC自动机的文章,这里实现了一个简单的AC自动机的小接口,我是实现自动机状 ...
- 汽车电子测试项目管理系统-TPA
概述 INTEWORK-TPA(Test Project Administrator, 以下简称TPA) 是一款集成的测试项目管理工具,它可以管理测试过程中的所有数据,包括需求.用例.样件.计划.报告 ...
- sshd安全加固
常见的防护措施: ——用户限制,黑白名单 ——更改验证方式(密码——>密钥对) ——防火墙..... 修改 sshd 配置文件 /etc/ssh/sshd_config -port 3389 # ...
- k8s安装之dashboard.yaml
这个我使用了nodeport方式导出来. 为了安装,最好在前面加个nginx作密码验证... 这个端口,可以通过防火墙禁掉. # Copyright 2017 The Kubernetes Autho ...
- gdb调试(二)
继续研究gdb相关的调试技巧,话不多说进入正题: 查看运行时数据: 这个上节中已经用过了,这里就不多说了,比较简单 还是有上节中的simple.c例子,不过得稍微做一些修改为了使用这些命令: simp ...
- Easy sssp(spfa判负环与求最短路)
#include<bits/stdc++.h> using namespace std; int n,m,s; struct node{ int to,next,w; }e[]; bool ...
- Caused by: java.nio.charset.MalformedInputException: Input length = 1
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/applicatio ...