android 字节码指令集,Java技术专题-了解字节码指令集调用

调用指令分布

invokeinterface

(Invoke interface method)

用以调用接口方法,在运行时搜索一个实现了这个接口方法的对象,找出适合的方法进行调用。

invokevirtual:

(Invoke instance method; dispatch based on class)

指令用于调用对象的实例方法,根据对象的实际类型进行分派:(静态分派[重载]、动态分派[重写])

invokestatic

(Invoke a class (static) method )

用以调用类方法、类操作变量的getter/setter方法等

invokespecial

(Invoke instance method)

指令用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。以及包含一些实例构造器()V 或者类构造器()V

**(Invoke instance method; special handling for superclass, private, and instance initialization method invocations )**

invokedynamic

(Invoke dynamic method)

JDK1.7新加入的一个虚拟机指令,相比于之前的四条指令,他们的分派逻辑都是固化在JVM内部,而invokedynamic则用于处理新的方法分派:它允许应用级别的代码来确定执行哪一个方法调用,只有在调用要执行的时候,才会进行这种判断,从而达到动态语言的支持。

public class JVMInstructionTest implements Runnable {

public JVMInstructionTest() {

System.out.println("constructor method");

}

private void s() {

System.out.println("private method");

}

static void print() {

System.out.println("static method");

}

void p() {

System.out.println("instance method");

}

public void d(String str) {

System.out.println("for method handle " + str);

}

static void ddd(String str) {

System.out.println("static method for method handle " + str);

}

public static void main(String[] args) throws Throwable {

/**

* invoke special

*/

JVMInstructionTest test = new JVMInstructionTest();

/**

* invoke special

*/

test.s();

/**

* invoke virtual

*/

test.p();

/**

* invoke static

*/

print();

/**

* invoke interface

*/

Runnable r = new JVMInstructionTest();

r.run();

/**

* Java 8中,lambda表达式和默认方法时,底层会生成和使用invoke dynamic

* invoke dynamic

*/

List list = Arrays.asList(1, 2, 3, 4);

list.stream().forEach(System.out::println);

}

@Override

public void run() {

System.out.println("interface method");

}

}

使用javap来反编译生成的class文件,首先看构造方法,编译器生成的字节码中是什么指令:

JVMInstructionTest test = new JVMInstructionTest();

0a95f12b70ad

image

很明显的,构造方法,invokespecial指令

s()为类的私有实例方法,同样的也是生成invokespecial指令;p()为实例方法,应该为invokevirtual指令,而print()为静态方法,应生成invokestatic指令,反编译结果如下:

0a95f12b70ad

image

我们的测试类JVMInstructionTest实现了Runnable接口,因此对于代码:

/**

* invoke interface

*/

Runnable r = new JVMInstructionTest();

r.run();

/**

*/

对于Lambda表达式,在Java 8中Lambda表达式和默认方法时,底层会生成和使用**invokedynamic**

> list.stream().forEach(System.out::println);

![image](https://upload-images.jianshu.io/upload_images/8631313-cc770b6f8daf16ac.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

使用**MethodHandle**

**/****

* invoke dynamic

*/

MethodHandles.Lookup lookup = MethodHandles.lookup();

MethodHandle mh = lookup.findVirtual(JVMInstructionTest.class, "d",

MethodType.methodType(void.class, String.class));

System.out.println(mh);

mh.bindTo(test).invoke("a");

mh = lookup.findStatic(JVMInstructionTest.class, "ddd",

MethodType.methodType(void.class, String.class));

mh.invoke("static");

从Java语言的角度来看,MethodHandle的使用方法和效果与反射有众多相似之处,不过,他们还是有以下区别:

java.lang.reflect.Method对象远比MethodHandle机制java.lang.invoke.MethodHandle对象所包含的信息多。

前者是方法在Java一端的全面映像,包含了方法的签名、描述符以及方法属性表中各种属性的Java端表示方式,还包含执行权限等运行信息。而后者仅仅包含了于执行该方法相关的信息。用通俗的话来讲,反射是重量级的,而MethodHandle是轻量级。

由于MethodHandle是对字节码的指令调用模拟,所以理论上虚拟机在这方面做的各种优化(如方法内联),在MethodHandle上也应当可以采用类似的思路去支持。而通过反射去调用方法则不行。

最关键的一点还在于:反射API设计目标只是为了Java语言服务的,而MethodHandle则设计成可服务于所有Java虚拟机上的语言,其中也包含Java语言。

invokedynamic指令

在某种程度上,invokedynamic指令与MethodHandle机制的作用是一样的,都是为了解决原有4条指令方法分派规则固化在虚拟机之中的问题,把如何查找目标方法的决定权从虚拟机转嫁到具体用户代码中,让用户有更高的自由度。而且,他们两者的思路也是可类比的,可以把他们想象成为了达成同一个目的,一个采用上层Java代码和API来实现,另一个用字节码和Class中其他属性、常量来完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值