关于Class的invokeDynamic指令
(2)invokedynamic指令 https://www.cnblogs.com/wade-luffy/p/6058087.html
public class InDyTest { public static void main(String[] args) { Runnable x = () -> { //System.out.println("Hello, World!"); }; } }
生成的Class结构如下:
Classfile /C:/Users/mazhi/Desktop/InDyTest.class Last modified 2018-7-5; size 986 bytes MD5 checksum 03d0c485e603b294e8de271d879c7b8f Compiled from "InDyTest.java" public class com.test01.InDyTest SourceFile: "InDyTest.java" BootstrapMethods: 0: #34 invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/la ng/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Lj ava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/Meth odType;)Ljava/lang/invoke/CallSite; Method arguments: #35 ()V #38 invokestatic com/test01/InDyTest.lambda$0:()V #39 ()V InnerClasses: public static final #45= #41 of #43; //Lookup=class java/lang/invoke/Meth odHandles$Lookup of class java/lang/invoke/MethodHandles minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Class #2 // com/test01/InDyTest #2 = Utf8 com/test01/InDyTest #3 = Class #4 // java/lang/Object #4 = Utf8 java/lang/Object #5 = Utf8 <init> #6 = Utf8 ()V #7 = Utf8 Code #8 = Methodref #3.#9 // java/lang/Object."<init>":()V #9 = NameAndType #5:#6 // "<init>":()V #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 Lcom/test01/InDyTest; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = NameAndType #17:#18 // run:()Ljava/lang/Runnable; #17 = Utf8 run #18 = Utf8 ()Ljava/lang/Runnable; #19 = InvokeDynamic #0:#16 // #0:run:()Ljava/lang/Runnable; #20 = Utf8 args #21 = Utf8 [Ljava/lang/String; #22 = Utf8 x #23 = Utf8 Ljava/lang/Runnable; #24 = Utf8 lambda$0 #25 = Utf8 SourceFile #26 = Utf8 InDyTest.java #27 = Utf8 BootstrapMethods #28 = Methodref #29.#31 // java/lang/invoke/LambdaMetafactory .metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lan g/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle; Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; #29 = Class #30 // java/lang/invoke/LambdaMetafactory #30 = Utf8 java/lang/invoke/LambdaMetafactory #31 = NameAndType #32:#33 // metafactory:(Ljava/lang/invoke/Met hodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invo ke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava /lang/invoke/CallSite; #32 = Utf8 metafactory #33 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/St ring;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke /MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; #34 = MethodHandle #6:#28 // invokestatic java/lang/invoke/Lamb daMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/Str ing;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/ MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; #35 = MethodType #6 // ()V #36 = Methodref #1.#37 // com/test01/InDyTest.lambda$0:()V #37 = NameAndType #24:#6 // lambda$0:()V #38 = MethodHandle #6:#36 // invokestatic com/test01/InDyTest.l ambda$0:()V #39 = MethodType #6 // ()V #40 = Utf8 InnerClasses #41 = Class #42 // java/lang/invoke/MethodHandles$Loo kup #42 = Utf8 java/lang/invoke/MethodHandles$Lookup #43 = Class #44 // java/lang/invoke/MethodHandles #44 = Utf8 java/lang/invoke/MethodHandles #45 = Utf8 Lookup { public com.test01.InDyTest(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init> ":()V 4: return LineNumberTable: line 4: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this Lcom/test01/InDyTest; public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #19, 0 // InvokeDynamic #0:run:()Ljava/la ng/Runnable; 5: astore_1 6: return LineNumberTable: line 7: 0 line 10: 6 LocalVariableTable: Start Length Slot Name Signature 0 7 0 args [Ljava/lang/String; 6 1 1 x Ljava/lang/Runnable; }
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import static java.lang.invoke.MethodHandles.lookup; public class TestMethod { static class ClassA { public void println(String s) { System.out.println(s); } } public static void main(String[] args) throws Throwable { Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA(); /* * 无论obj最终是哪个实现类,下面这句都能正确调用到println方法 **/ getPrintlnMH(obj).invokeExact("icyfenix"); } private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable { /* * MethodType:代表“方法类型”,包含了方法的返回值(methodType()的第一个参数) * 和具体参数(methodType() 第二个及以后的参数) */ MethodType mt = MethodType.methodType(void.class, String.class); /* * lookup()方法来自于MethodHandles.lookup,这句的作用是在指定类中查找符合给定的方法名称、方法类型, * 并且符合调用权限的方法句柄 * 因为这里调用的是一个虚方法,按照Java语言的规则,方法第一个参数是隐式的,代表该方法的接收者,也即是this指向的对象, * 这个参数以前是放在参数列表中进行传递的,而现在提供了bindTo()方法来完成这件事情 */ return lookup().findVirtual(reveiver.getClass(), "println", mt).bindTo(reveiver); } }
import static java.lang.invoke.MethodHandles.lookup; import java.lang.invoke.CallSite; import java.lang.invoke.ConstantCallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; public class InvokeDynamicTest { public static void main(String[] args) throws Throwable { INDY_BootstrapMethod().invokeExact("icyfenix"); } public static void testMethod(String s) { System.out.println("hello String:" + s); } public static CallSite BootstrapMethod( MethodHandles.Lookup lookup, String name, MethodType mt) throws Throwable { return new ConstantCallSite( lookup.findStatic(InvokeDynamicTest.class, name, mt)); } private static MethodType MT_BootstrapMethod() { return MethodType.fromMethodDescriptorString( "(Ljava/lang/invoke/MethodHandles $Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", null); } private static MethodHandle MH_BootstrapMethod() throws Throwable { return lookup().findStatic( InvokeDynamicTest.class, "BootstrapMethod", MT_BootstrapMethod()); } private static MethodHandle INDY_BootstrapMethod() throws Throwable { CallSite cs = (CallSite) MH_BootstrapMethod().invokeWithArguments( lookup(), "testMethod", MethodType.fromMethodDescriptorString("(Ljava/lang/String;)V", null)); return cs.dynamicInvoker(); } }
import static java.lang.invoke.MethodHandles.lookup; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; public class Test02 { class GrandFather { void thinking() { System.out.println("i am grandfather"); } } class Father extends GrandFather { void thinking() { System.out.println("i am father"); } } class Son extends Father { void thinking() { try { MethodType mt = MethodType.methodType(void.class); MethodHandle mh = lookup().findVirtual( GrandFather.class, "thinking", mt) .bindTo(new Test02().new GrandFather()); mh.invokeExact(); } catch (Throwable e) { } } } public static void main(String[] args) { (new Test02().new Son()).thinking(); } }
关于Class的invokeDynamic指令的更多相关文章
- invokedynamic指令
Java虚拟机的字节码指令集的数量从Sun公司的第一款Java虚拟机问世至JDK 7来临之前的十余年时间里,一直没有发生任何变化.随着JDK 7的发布,字节码指令集终于迎来了第一位新成员--invok ...
- 方法引用(Method reference)和invokedynamic指令详细分析
方法引用(Method reference)和invokedynamic指令详细分析 invokedynamic是jvm指令集里面最复杂的一条.本文将详细分析invokedynamic指令是如何实现方 ...
- 动态方法调用秘密武器 —— invokedynamic 指令解读 - MethodHandle
原文:https://juejin.im/book/5c25811a6fb9a049ec6b23ee/section/5ccc66dd518825403b5975fb import java.lang ...
- invokedynamic字节码指令
1. 方法引用和invokedynamic invokedynamic是jvm指令集里面最复杂的一条.本文将从高观点的角度下分析invokedynamic指令是如何实现方法引用(Method refe ...
- JVM-字节码指令
Java虚拟机字节码指令 了解了class文件,我觉得就很有必要去了解一下JVM中的字节码指令,那样堆class文件以及JVM运行机制也后很大的帮助. Java虚拟机的指令由一个字节长度的,代表着某种 ...
- Scripting Java #3:Groovy与invokedynamic
只需看看今天Groovy语言实现机制.在此之前,是第一个推倒静态类型与动态类型语言在实现上面的一些差异. 静态类型 vs. 动态类型 看以下这个简单的栗子. def addtwo(a, b) { re ...
- java7 invokedynamic命令深入研究
在看java虚拟机字节码执行引擎的时候,里面提到了java虚拟机里调用方法的字节码指令有5种: invokestatic //调用静态方法 invokespecial //调用私有方法.实例构造器方法 ...
- jvm理论-字节码指令
Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...
- Java字节码指令
1. 简介 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成. 由于Java虚拟机采用面向操作数栈而不是寄存 ...
随机推荐
- (最小生成树 )还是畅通工程 -- HDU--1233
链接: http://acm.hdu.edu.cn/showproblem.php?pid=1233 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- [转自知乎] 从github上下载单个文件夹
原文地址: 如何从 GitHub 上下载单个文件夹? 注意:如果是在公司网络环境的话需要配置可以访问外网的代理,否则 svn checkout 时会出错.
- 测试与发布(Alpha版本)——小谷围驻广东某工业719电竞大队
测试与发布(Alpha版本)--小谷围驻广东某工业719电竞大队 一.引言 1.需求规格说明书: https://www.cnblogs.com/TaoTaoLV1/p/9819913.html 2. ...
- memcached分布式缓存系统
在数据驱动的Web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载.缓存是解决这个问题的好办法.但是ASP.NET中的虽然已经可以实现对页面局部进行缓存,但还是不够灵活.此时 ...
- Tomcat跨域访问配置
下载cors-filter-1.7.jar,java-property-utils-1.9.jar这两个库文件,放到Tomcat的lib目录下. D:\Program Files\Tomcat-7.0 ...
- 让Easy UI 的DataGrid直接内嵌的JSON对象,并重写form load 方法
前言 我有这样的JSON对象 { "UserName": "jf", "UserPwd": "123456", &quo ...
- sqlserver错误2,error 40
打开配置管理器:开始-> sqlserver2014->配置工具->配置管理器 选择sqlserver服务,并将右侧箭头的指向右击设为启动就OK了
- jsp(Java的服务网页)$javabean
JSP:Java Server Page(Java的服务网页),也是Java的动态网页. JSP的本质:其实就是一个Servlet. JSP---->翻译成Servlet类---->编 ...
- ASP.NET MVC Areas View 引用 外部母版视图
ASP.NET MVC Area => Areas View 引用 外部母版视图 创建项目:MVCSite.Area 创建mvc area 1.Areas View 引用 外部母版视图 1.1 ...
- iOS App的加固保护原理
本文由 网易云发布. 本文从攻防原理层面解析了iOS APP的安全策略.iOS以高安全性著称,但它并非金刚不坏之身.对于信息安全而言,止大风于青萍之末是上上策,杭研深入各个细节的研发工作,正是网易产 ...