Java InvokeDynamic(第1部分)

动态调用instructionน指令instructionอิมพลีเมนต์เพิ่มเข้ามาในJava 7(JVM)动态บนJVMเช่นJRuby,Groovy(เราเลยไม่ค่อยได้ใช้เท่าไร)ซึ่งแต่ Reflectionอในimplementองใช้java Reflectionในการ实现方法调用call performaceที่ต่ำเนื่องจากว่าJVMจะ优化ลำบาก

์อมไพเลอร์Javac版本7จะยังไม่มีการ编译ที่ให้ผลลัพธ์ที่เป็น动态调用 ออกมา ภาษาจาวาเองเริ่มนำ 动态调用 มาใช้ในเวอร์ชัน 8

背景 JVM จะมี instruction ที่ใช้ในการเรียก method ที่แตกต่างกันดังนี้invokespecialกรับเรหยก实例私有方法หรือ构造函数(非虚拟)invokestatic静态方法invokevirtual实例方法ที่เป็นvirtualพวก受保护的,公共的,默认可见性invokeinterfaceสำหรับเรียก接口虚拟方法vir지เหตที่มีinvokevirtualและinvokeinterfaceเพราะว่าinvokervirtualคอมไพล์เลอร์จะรู้ตำเหน่งของ方法 ไม่ได้ปล。 虚拟术语虚拟术语术语C ++的++นภาษาแรแนะะร์ครับ

dynamicให้งมีdynamic dynamic dynamic constant constant constant constant constantได้ได้ได้ได้ได้ได้ได้ได้ได้ได้ได้ได้

  1. CONSTANT_MethodHandle_infoเป็น数据结构ที่เอาไว้解析引用ังยังinvokespectal,invokestatic,invokevirtual,invokeintervaceในภาษาจาวาจะ代表โดยjava.lang.invoke.MethodHandleCONSTANT_MethodType_infoเอาไว้เป็น类型描述符ของ方法(参数และ返回类型)ในภาษาจาวาวาจะ表示โดยjava.lang.invoke.MethodTypeCONSTANT_InvokeDynamic_infoไว้อาไว้解析参考referenceยัง引导方法และ可选参数ยังไม่ต้องสนใจในตอนนี้

Stringรับในบทความนี้เราจะมาเขียนจาวาให้ทำกาให้ทำการให้ทำกรียก方法String.concat(String)CONSTANT_MethodHandleและCONSTANT_MethodTypeconstantาทยังไงใน常量池โดยใช้Java API

อ่านคำอธิบายจาก评论เอานะครับ

สำหรับใครที่ยังอ่าน bytecode ไม่ออก ผมมีบทความเก่าอยู่ ลองอ่านดูนะครับ
JVM 1
JVM 2
JVM 3

package th.co.geniustree.indy;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public class MethodHandleTest {

    public static void main(String[] args) throws Throwable {
        //Lookup เป็น Factory สำหรับเอาไว้สร้าง MethodHandle
        final MethodHandles.Lookup lookup = MethodHandles.lookup();

        // เราจะอธิบายว่าเราต้องการ method ที่มี return type เป็นอะไร และ param เป็นอะไร
        //ในที่นี้เราจะเรียก String.concat(String)
        //กรณีที่ compiler เป็นคนจัดการให้ ตรงนีจะเป็น CONSTANT_MethodType
        //CONSTANT_MethodType --> (Ljava/lang/String;)Ljava/lang/String;
        //โดย L className ; เป็น field descriptor L หมายถึง reference type ใดๆ ส่วน className จะแทน . ด้วย /
        MethodType returnStringAndStringParamMethosType = MethodType.methodType(String.class, String.class);


        // สร้าง MethodHandle เพื่อห่อหุ่มเอา invokevirtual  java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String; เอาไว้สำหรับ invoke
        //ขั้นตอนนี้จะทำการ access checking ด้วยว่ามีสิทธิเข้าถึงไหม ซึ่งจะต่างจาก Reflection ตรงที่ reflection จะ check ทุกครั้งที่ invoke method ดังนั้นตรงนี้ MethodHandle จะเร็วกว่า
        // เพราะโดยปกติแล้ว lookup.findXxx จะทำครั้งเดียวแล้วเก็บ method handle instance เอาไว้ invoke()
        MethodHandle concatMethodHandle = lookup.findVirtual(String.class, "concat",returnStringAndStringParamMethosType);

        //ถ้าเป็น bytecode ก็จะเทียบเท่ากับ
        //ldc "Hello"  --> push "Hello" reference to operand stack
        //ldc "World"  --> push "World" reference to operand stack
        //invokevirtual  java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
        final String result = (String) concatMethodHandle.invokeExact("Hello", "World");
        System.out.println(result); // print "HelloWorld"
    }
}

from: https://dev.to//pramoth/java-invokedynamic-part-1-275e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值