Upgrade to Pro — share decks privately, control downloads, hide ads and more …

10分で完全に理解するInvokeDynamic / 10min To Understand ...

Ikuo Suyama
February 22, 2022

10分で完全に理解するInvokeDynamic / 10min To Understand InvokeDynamic

社内勉強会のLT資料です。

Ikuo Suyama

February 22, 2022
Tweet

More Decks by Ikuo Suyama

Other Decks in Programming

Transcript

  1. +7.ϚγϯޠΛ೷͍ͯΈΔ *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke {

    public static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I 6: pop 7: new #3 // class invoke/others/Invokes 10: dup 11: invokespecial #4 // Method "<init>":()V 14: astore_2 15: aload_2 16: iload_1 17: invokevirtual #5 // Method method:(I)I 20: pop 21: aload_2 22: astore_3 23: aload_3 24: iload_1 25: invokeinterface #6, 2 // InterfaceMethod invoke/others/ IInvoke.interfaceMethod:(I)I 30: pop 31: return *OWPLFTKWN NBJOϝιουͷΈൈਮ
  2. *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke { public

    static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I 6: pop 7: new #3 // class invoke/others/Invokes 10: dup 11: invokespecial #4 // Method "<init>":()V 14: astore_2 15: aload_2 16: iload_1 17: invokevirtual #5 // Method method:(I)I 20: pop 21: aload_2 22: astore_3 23: aload_3 24: iload_1 25: invokeinterface #6, 2 // InterfaceMethod invoke/others/ IInvoke.interfaceMethod:(I)I 30: pop 31: return *OWPLFTKWN NBJOϝιουͷΈൈਮ +7.ϚγϯޠΛ೷͍ͯΈΔ
  3. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου JOWPLFEZOBNJDͷ൓ର͸JOWPLFTUBUJD͡Όͳ͍ w *OWPLFEZOBNJD w ϚδͰ%ZOBNJDʢʁʣ ͷ࣮ߦ Ͳ͏΍Β͜Μͳ͔Μ͡ JOWPLFTUBUJD͸͋Δ͕ɺ JOWPLFEZOBNJDͷ൓ରͰ͸ͳ͔ͬͨ
  4. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου ʢ࠶ܝʣ͜Μͳ͔Μ͡ w *OWPLFEZOBNJD w ϚδͰ%ZOBNJDʢʁʣ ͷ࣮ߦ *OWPLFEZOBNJD͕ͲΕ΄Ͳ%ZOBNJD͔Λ஌ΔͨΊʹɺ *OWPLFTUBUJD͕ͲͷΑ͏ʹϝιουΛ࣮ߦ͢Δ͔Λ؆୯ʹݟ͍ͯ͜͏
  5. *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke { public

    static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { Constant pool: #2 = Methodref #3.#22 // invoke/others/Invokes.staticMethod:(I)I #3 = Class #23 // invoke/others/Invokes #16 = Utf8 (I)I #17 = Utf8 staticMethod #22 = NameAndType #17:#16 // staticMethod:(I)I #23 = Utf8 invoke/others/Invokes : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I : *OWPLFTKWN ൈਮ +7.ϚγϯޠΛ೷͍ͯΈΔ
  6. *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke { public

    static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { Constant pool: #2 = Methodref #3.#22 // invoke/others/Invokes.staticMethod:(I)I #3 = Class #23 // invoke/others/Invokes #16 = Utf8 (I)I #17 = Utf8 staticMethod #22 = NameAndType #17:#16 // staticMethod:(I)I #23 = Utf8 invoke/others/Invokes : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I : *OWPLFTKWN ൈਮ +7.ϚγϯޠΛ೷͍ͯΈΔ $POTUBOU1PPMͱ͍͏΍ͭͷ*OEFYΛࢦఆͯ͠ࢀর͍ͯ͠Δ
  7. *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke { public

    static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { Constant pool: #2 = Methodref #3.#22 // invoke/others/Invokes.staticMethod:(I)I #3 = Class #23 // invoke/others/Invokes #16 = Utf8 (I)I #17 = Utf8 staticMethod #22 = NameAndType #17:#16 // staticMethod:(I)I #23 = Utf8 invoke/others/Invokes : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I : *OWPLFTKWN ൈਮ +7.ϚγϯޠΛ೷͍ͯΈΔ $POTUBOU1PPMʹ͸༷ʑͳछྨ͕͋Δ͕ɺଟ͘͸ଞͷ$1΁ͷࢀর ࠷ऴతʹࢀর͞ΕΔͷ͸6UGܕͭ·Γͨͩͷจࣈྻ
  8. *OWPLFTKBWB package invoke.others; public class Invokes implements IInvoke { public

    static void main(String[] args) { int i = 1; Invokes.staticMethod(i); Invokes invs = new Invokes(); invs.method(i); IInvoke iinvs = invs; iinvs.interfaceMethod(i); } public int method(int i) { return i; } public static int staticMethod(int i) { return i; } @Override public int interfaceMethod(int i) { return i; } } interface IInvoke { int interfaceMethod(int i); } ❯ javac Invokes.java ❯ javap -v -p -s -constants Invokes.class > Invokes.jvm Compiled from "Invokes.java" public class invoke.others.Invokes implements invoke.others.IInvoke { Constant pool: #2 = Methodref #3.#22 // invoke/others/Invokes.staticMethod:(I)I #3 = Class #23 // invoke/others/Invokes #16 = Utf8 (I)I #17 = Utf8 staticMethod #22 = NameAndType #17:#16 // staticMethod:(I)I #23 = Utf8 invoke/others/Invokes : public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2: iload_1 3: invokestatic #2 // Method staticMethod:(I)I : *OWPLFTKWN ൈਮ +7.ϚγϯޠΛ೷͍ͯΈΔ ͭ·ΓɺίϯύΠϧ࣌Ͱ͸ͳ͘ɺ࣮ߦ࣌ʹ +7.͕ର৅ϝιουΛݕࡧͯ͠ಈతʹղܾ˞͍ͯ͠Δʂ ˞.FUIPE3FTPMVUJPO࢓༷
  9. public static void main(java.lang.String[]); Code: 0: iconst_1 1: istore_1 2:

    iload_1 3: invokestatic #2 // Method staticMethod:(I)I : *OWPLFTKWN ൈਮ όΠφϦΛ೷͍ͯΈΔ invokestatic Operation Invoke a class (static) method Format 
 invokestatic
 indexbyte1
 indexbyte2
 Forms invokestatic = 184 (0xb8) ͪͳΈʹόΠφϦ͸͜Μͳ͔Μ͡ɺ ͳΜͱ̏#ZUF͔͠ͳ͍
  10. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου JOWPLFTUBUJD͸%ZOBNJDͳ*OWPLF w *OWPLFEZOBNJD w ϚδͰ%ZOBNJDʢʁʣ $1͔ΒϝιουΛ ಈతʹݕࡧղܾ ࣮ͯ͠ߦ ϝιου͸࣮ߦ࣌ʹಈతʹղܾ͞ΕΔ͕ɺ ͦͷݕࡧର৅͸FYUFOET JNQMFNFOUT౳+BWBͷݴޠ࢓༷ʹڧ͘ґଘ͢Δ Ͳ͏΍Β͜Μͳ͔Μ͡
  11. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου ʢ࠶ܝʣ͜Μͳ͔Μ͡ w *OWPLFEZOBNJD w ϚδͰ%ZOBNJDʢʁʣ Ͱ͸JOWPLFEZOBNJD͸ɺͲΕ΄Ͳ%ZOBNJDͳͷ͔ʁ ࣮ߦର৅Λ +BWBͷݴޠ࢓༷ʹै͍ +7.಺Ͱݕࡧ࣮ͯ͠ߦ
  12. package invoke.dynamic; public class InvokeDynamicSimple { public static void main(String[]

    args) { Runnable r = () -> System.out.println("Hello"); r.run(); } } ❯ javac InvokeDynamicSimple.java ❯ javap -v -s -constants InvokeDynamicSimple.class > InvokeDynamicSimple.jvm public class invoke.dynamic.InvokeDynamicSimple Constant Pool: #2 = InvokeDynamic #0:#23 // #0:run:()Ljava/lang/Runnable; #23 = NameAndType #35:#36 // run:()Ljava/lang/Runnable; : { public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; 5: astore_1 6: aload_1 7: invokeinterface #3, 1 // InterfaceMethod java/lang/Runnable.run:()V 12: return } SourceFile: "InvokeDynamicSimple.java" InnerClasses: public static final #50= #49 of #53; // Lookup=class java/lang/invoke/ MethodHandles$Lookup of class java/lang/invoke/MethodHandles BootstrapMethods: 0: #20 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/ MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/ MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/ CallSite; Method arguments: #21 ()V #22 REF_invokeStatic invoke/dynamic/InvokeDynamicSimple.lambda$main$0:()V #21 ()V *OWPLF%ZOBNJD4JNQMFKBWB *OWPLF%ZOBNJD4JNQMFKWN -BNCEB͕JOWPLFEZOBNJDͰ ࣮ݱ͞Ε͍ͯΔ͜ͱ͸ શਓྨڞ௨ೝࣝͳͷͰɺ ͱΓ͋͑ͣίϯύΠϧˍσίϯύΠϧ ࠶ͼ+7.ϚγϯޠΛ೷͍ͯΈΔ
  13. package invoke.dynamic; public class InvokeDynamicSimple { public static void main(String[]

    args) { Runnable r = () -> System.out.println("Hello"); r.run(); } } ❯ javac InvokeDynamicSimple.java ❯ javap -v -s -constants InvokeDynamicSimple.class > InvokeDynamicSimple.jvm public class invoke.dynamic.InvokeDynamicSimple Constant Pool: #2 = InvokeDynamic #0:#23 // #0:run:()Ljava/lang/Runnable; #23 = NameAndType #35:#36 // run:()Ljava/lang/Runnable; : { public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; 5: astore_1 6: aload_1 7: invokeinterface #3, 1 // InterfaceMethod java/lang/Runnable.run:()V 12: return } SourceFile: "InvokeDynamicSimple.java" InnerClasses: public static final #50= #49 of #53; // Lookup=class java/lang/invoke/ MethodHandles$Lookup of class java/lang/invoke/MethodHandles BootstrapMethods: 0: #20 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/ MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/ MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/ CallSite; Method arguments: #21 ()V #22 REF_invokeStatic invoke/dynamic/InvokeDynamicSimple.lambda$main$0:()V #21 ()V *OWPLF%ZOBNJD4JNQMFKBWB *OWPLF%ZOBNJD4JNQMFKWN ࠶ͼ+7.ϚγϯޠΛ೷͍ͯΈΔ ϋΠग़·ͨ͠ɺJOWPLFEZOBNJD ͖ͬ͞ͱಉ͘͡ɺ$1Λࢀর͍ͯ͠Δ Ͱ͋Ζ͏͜ͱ͸૝૾͕ͭ͘
  14. package invoke.dynamic; public class InvokeDynamicSimple { public static void main(String[]

    args) { Runnable r = () -> System.out.println("Hello"); r.run(); } } ❯ javac InvokeDynamicSimple.java ❯ javap -v -s -constants InvokeDynamicSimple.class > InvokeDynamicSimple.jvm public class invoke.dynamic.InvokeDynamicSimple Constant Pool: #2 = InvokeDynamic #0:#23 // #0:run:()Ljava/lang/Runnable; #23 = NameAndType #35:#36 // run:()Ljava/lang/Runnable; : { public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; 5: astore_1 6: aload_1 7: invokeinterface #3, 1 // InterfaceMethod java/lang/Runnable.run:()V 12: return } SourceFile: "InvokeDynamicSimple.java" InnerClasses: public static final #50= #49 of #53; // Lookup=class java/lang/invoke/ MethodHandles$Lookup of class java/lang/invoke/MethodHandles BootstrapMethods: 0: #20 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/ MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/ MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/ CallSite; Method arguments: #21 ()V #22 REF_invokeStatic invoke/dynamic/InvokeDynamicSimple.lambda$main$0:()V #21 ()V *OWPLF%ZOBNJD4JNQMFKBWB *OWPLF%ZOBNJD4JNQMFKWN ࠶ͼ+7.ϚγϯޠΛ೷͍ͯΈΔ ͔͠͠$1ʹ͸ଘࡏ͠ͳ͍ʂ ϦϑΝϨϯεʹΑΔͱɺ ͜Ε͸#PPUTUSBQ.FUIPETͷ ΠϯσοΫεΛࢀর͍ͯ͠Δ 5IF$0/45"/5@*OWPLF%ZOBNJD@JOGP 4USVDUVSFT bootstrap_method_attr_index The value of the bootstrap_method_attr_index item must be a valid index into the bootstrap_methods array of the bootstrap method table of this class file (§4.7.23).
  15. #PPU4USBQ.FUIPE#4.JTԿ BootstrapMethods: 0: #20 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:( Ljava/lang/invoke/MethodHandles$Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType; Ljava/lang/invoke/MethodType;

    Ljava/lang/invoke/MethodHandle; Ljava/lang/invoke/MethodType; )Ljava/lang/invoke/CallSite; Method arguments: #21 ()V #22 REF_invokeStatic invoke/dynamic/InvokeDynamicSimple.lambda$main$0:()V #21 ()V ͜Μͳॻࣜʹͳ͍ͬͯͯɺଟগෳࡶ͕ͩ
  16. #PPU4USBQ.FUIPE#4.JTԿ BootstrapMethods: 0: #20 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:( Ljava/lang/invoke/MethodHandles$Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType; Ljava/lang/invoke/MethodType;

    Ljava/lang/invoke/MethodHandle; Ljava/lang/invoke/MethodType; )Ljava/lang/invoke/CallSite; Method arguments: #21 ()V #22 REF_invokeStatic invoke/dynamic/InvokeDynamicSimple.lambda$main$0:()V #21 ()V ௥Ճͷ੩తҾ਺ σϑΥϧτҾ਺ +7.͕ܭࢉऔಘ ฦΓ஋ ͜Μͳॻࣜʹͳ͍ͬͯͯɺଟগෳࡶ͕ͩ ཁ఺ɿ ͳʹ͔ͷ4UBUJDϝιουͱɺͦͷҾ਺Λࢦఆ͍ͯ͠Δ ࣮ߦ͢Δͱ$BMM4JUFΛฦ͢
  17. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου *OWPLF%ZOBNJD͸ϚδͰ%ZOBNJD w *OWPLFEZOBNJD w ॳճ࣮ߦ࣌ʹ #PPUTUSBQ.FUIPEͰࢦఆ͞ ΕͨϝιουΛ࣮ߦ͠ɺ࣮ߦର ৅Λͦͷ݁ՌͰܾΊΔ ࣮ߦର৅Λ +BWBͷݴޠ࢓༷ʹै͍ +7.಺Ͱݕࡧ࣮ͯ͠ߦ ͭ·Γ͜͏͍͏͜ͱ
  18. w JOWPLFTUBUJD w 4UBUJDϝιου w JOWPLFTQFDJBM w ίϯετϥΫλͳͲ w JOWPLFWJSUVBM

    w Πϯελϯεϝιου w JOWPLFJOUFSGBDF w ΠϯλʔϑΣʔεܦ༝ͷϝιου *OWPLF%ZOBNJD͸ϚδͰ%ZOBNJD w *OWPLFEZOBNJD w ॳճ࣮ߦ࣌ʹ #PPUTUSBQ.FUIPEͰࢦఆ͞ ΕͨϝιουΛ࣮ߦ͠ɺ࣮ߦର ৅Λͦͷ݁ՌͰܾΊΔ ίϯύΠϥ͕#4.Λు͖͑͢͞Ε͹ԿͰ΋͋Γ ࣮ߦ࣌ʹ+7.ʹଘࡏ͠ͳ͍ϝιου͢Βղܾɾ࣮ߦͰ͖Δਆͷ೗͖ྗ ࣮ࡍʹ-BNCEBͰ͸ɺ࣮ߦΫϥε͕#4.ʹΑΓ࿉੒͞ΕΔ ͭ·Γ͜͏͍͏͜ͱ ࣮ߦର৅Λ +BWBͷݴޠ࢓༷ʹै͍ +7.಺Ͱݕࡧ࣮ͯ͠ߦ
  19. ࿦ΑΓόΠφϦ package invoke.dynamic; public class InvokeDynamicSimple { public static void

    main(String[] args) { Runnable r = () -> System.out.println("Hello"); r.run(); } } public class invoke.dynamic.InvokeDynamicSimple Constant Pool: #2 = InvokeDynamic #0:#23 // #0:run:()Ljava/lang/Runnable; #23 = NameAndType #35:#36 // run:()Ljava/lang/Runnable; : { public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; *OWPLF%ZOBNJD4JNQMFKBWB invokedynamic Operation Invoke a dynamically-computed call site Format invokedynamic
 indexbyte1
 indexbyte2
 0
 0
 Forms invokedynamic = 186 (0xba) Description First, the unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (§2.6), The values of the third and fourth operand bytes must always be zero. JOWPLFEZOBNJD YCB *OWPLF%ZOBNJD4JNQMFDMBTT *OWPLF%ZOBNJD4JNQMFKWN
  20. ࿦ΑΓόΠφϦ package invoke.dynamic; public class InvokeDynamicSimple { public static void

    main(String[] args) { Runnable r = () -> System.out.println("Hello"); r.run(); } } public class invoke.dynamic.InvokeDynamicSimple Constant Pool: #2 = InvokeDynamic #0:#23 // #0:run:()Ljava/lang/Runnable; #23 = NameAndType #35:#36 // run:()Ljava/lang/Runnable; : { public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: (0x0009) ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=2, args_size=1 0: invokedynamic #2, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable; *OWPLF%ZOBNJD4JNQMFKBWB invokedynamic Operation Invoke a dynamically-computed call site Format invokedynamic
 indexbyte1
 indexbyte2
 0
 0
 Forms invokedynamic = 186 (0xba) Description First, the unsigned indexbyte1 and indexbyte2 are used to construct an index into the run-time constant pool of the current class (§2.6), The values of the third and fourth operand bytes must always be zero. JOWPLFEZOBNJD YCB *OWPLF%ZOBNJD4JNQMFDMBTT *OWPLF%ZOBNJD4JNQMFKWN ͨͬͨ#ZUFͰ͜Ε͕දݱ͞Ε͍ͯΔͳΜͯ ඒ͍͠ ͦ͏͸ࢥΘΜ͔Ͷʁ