Рубрики
Без рубрики

Java вызвал динамический (часть 1)

Поймите призывную динамику к Лямбде. Помеченный java, вызываемый динамический, methodhandle.

invokedynamic – это инструкция, которая импортируется в вашу квартиру, добавленная в java 7 (JVM) По основной цели делать и быть с человеком, который работает с динамикой фреймворка или языка в JVM, таким как JRuby, Groovy (мы редко используем много), которому до этого придется использовать отражение java для реализации вызова метода, что снизит производительность, потому что JVM будет оптимизировать Хлопотный

Компилятор javac версии 7 также не будет компилировать результаты вызванный динамический Из самого языка Java начали выводить invokedynamic, используемый в версии 8

Предыстория JVM Там будет инструкция, используемая для вызова метода по-другому, следующим образом:

  1. вызывает специальный конструктор สำหรับเรียก экземпляра частного метода หรือ (невиртуальный)
  2. invokestatic для вызова статического метода
  3. вызов виртуального สำหรับเรียก метода экземпляра ที่เป็น виртуальный พวก защищенный, общедоступный, видимость по умолчанию
  4. интерфейс вызова для виртуального метода интерфейса вызова

สาเหตที่มี invokevirtual และ invokeinterface เพราะว่า invokervirtual คอมไพล์เลอร์จะรู้ตำเหน่งของ способ ที่จะเรียกใน виртуальная таблица ได้ในตอนคอมไพล์ ส่วน invokeinterface เราจะ предположить индекс ใน виртуальную таблицу(Таблица виртуальных методов) В сборнике эпизодов нет

..Я понимаю, что виртуальный – это термин, используемый в c++ в качестве первого языка. но не уверен.

Таким образом, invokedynamic может запускать байт-код java, необходима дополнительная информация о времени выполнения, добавленная в файл класса в разделе, который является постоянным пулом, следующим образом:

  1. CONSTANT_MethodHandle_info – это структура данных, которая разрешает ссылку на invokespectal, invokestatic, invokevirtual, invokeintervace на языке Java для представления с помощью java.lang.invoke. Способ обработки
  2. CONSTANT_MethodType_info это дескриптор типа метода (параметра и возвращаемого типа) на языке Java для представления с помощью java.lang.invoke. Тип метода
  3. CONSTANT_InvokeDynamic_info เอาไว้ разрешить ссылку ไปยงง метод начальной загрузки และ необязательный аргумент/| Кроме того, сейчас мне это неинтересно

Метод String สำหรับในบทความนี้เราจะมาเขียนจาวาให้ทำการเรียก.функция concat(строка) เพื่อจำลองให้เห็นว่า CONSTANT_MethodHandle และ CONSTANT_MethodType มีบทบาทยังไงใน постоянный пул โดยใช้ API-интерфейса Java

Прочитайте описание из комментария.

สำหรับใครที่ยังอ่าน байт-код ไม่ออก ผมมีบทความเก่าอยู่ ลองอ่านดูนะครับ в 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"
    }
}

Оригинал: “https://dev.to/pramoth/java-invokedynamic-part-1-275e”