没有合适的资源?快使用搜索试试~ 我知道了~
JVM调用Lambda的表达式实现方法原理详解.docx
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 183 浏览量
2022-07-03
11:04:02
上传
评论
收藏 32KB DOCX 举报
温馨提示
试读
13页
Java中方法的调用对应字节码有5条指令: invokestatic:用于调用静态方法。 invokespecial:用于调用实例构造器方法、私有方法和父类中的方法。 invokevirtual:用于调用所有的虚方法。 invokeinterface:用于调用接口方法,会在运行时再确定一个实现该接口的对象。 invokedynamic:先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法。
资源推荐
资源详情
资源评论
Java 中方法的调用对应字节码有 5 条指令:
invokestatic:用于调用静态方法。
invokespecial:用于调用实例构造器方法、私有方法和父类中的方法。
invokevirtual:用于调用所有的虚方法。
invokeinterface:用于调用接口方法,会在运行时再确定一个实现该接口的对象。
invokedynamic:先在运行时动态解析出调用点限定符所引用的方法,然后再执行
该方法。
invokedynamic与前 4 条指令不同的是,该指令分派的逻辑是由用户指定,
用于支持动态类型语言特性(相关概念后文会详细描述)。
Java 中有非虚方法和虚方法,前者是指在解析阶段可以确定的唯一的调用
版本,如静态方法、构造器方法、父类方法(特指在子类中使用 super 调用,
而不是在客户端使用对象引用调用)、私有方法(上述几种方法是使用
invokestatic 和 invokespecial 指令调用的)以及被 final 修饰的方法(使用
invokevirtual 调用),这些方法在类加载阶段就会把方法的符号引用解析为直
接引用;除此之外的都是虚方法,虚方法则只能在运行期进行分派调用。
分派
分派分为静态和动态,同时还会根据宗量数(可以简单理解为影响方法选
择的因素,如方法的接收者和参数)分为静态单分派、静态多分派、动态
单分派、动态多分派。
静态分派
静态分派就是指根据静态类型(方法中定义的变量)来决定方法执行版本的分
派动作,Java 中典型的静态分派就是方法重载。下面先来看段代码示例:
public class StaticDispatch{
static abstract class Human{}
static class Man extends Human{ }
static class Woman extends Human{}
public void sayHello(Human guy){
System.out.println("hello,guy!");
}
public void sayHello(Man guy){
System.out.println("hello,gentleman!");
}
public void sayHello(Woman guy){
System.out.println("hello,lady!");
}
public static void main(String[] args) {
StaticDispatch sr = new StaticDispatch();
Human man = new Man();
Human woman = new Woman();
sr.sayHello(man);
sr.sayHello(woman);
}
}
下面的结果是否跟你想的是否一样呢?
hello,guy!
hello,guy!
这里全都是调用的参数为 Human 类型的方法,原因就是在 main 方法中定义的
变量类型都是 Human,这个就属于静态类型,而等于后面的对象则属于实际类
型,实际类型只能在运行期间获取到,因此编译器在编译阶段时只能根据静态
类型选取到对应的方法,所以这里打印的都是"hello,guy!"。
不过不要想当然的认为静态类型就只会匹配到一个唯一的方法,如果有自动拆、
装箱,变长参数,向上转型等参数,就可以匹配到多个,不过它们是存在优先
级关系的。
动态分派
Java 里面的动态分派与它的多态性息息相关,即方法重写,如下面的代码:
public class DynamicDispatch {
static abstract class Virus{ //病毒
protected abstract void ill();//生病
}
static class Cold extends Virus{
@Override
protected void ill() {
System.out.println("感冒了,好不舒服!");
}
}
static class CoronaVirus extends Virus{//冠状病毒
@Override
protected void ill() {
System.out.println("粘膜感染,空气传播,请带好口罩!");
}
}
public static void main(String[] args) {
Virus clod=new Cold();
clod.ill();
clod = new CoronaVirus();
clod.ill();
}
}
这里的输出结果相信大家都清楚,但你是否深入考虑过它的调用细节呢?先来
看看字节码:
剩余12页未读,继续阅读
资源评论
小兔子平安
- 粉丝: 209
- 资源: 1940
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功