2016-07-28 21 views
3

Ich habe diese Klasse, und ich kompiliere es.Java Bytecode, Java Lieferant und aufgerufene dynamische Argument

package org.test; 

import java.util.function.Supplier; 

public class Test { 
    static String get() { return "!!"; } 

    public static void main(String[] args) { 
     Supplier<String> sup = Test::get; 
     System.out.println(sup.get()); 
    } 
} 

Dann hinein zu schauen versuchen Bytecode ich folgenden Anfang public static void main Funktion erhalten:

public static void main(java.lang.String[]); 
    descriptor: ([Ljava/lang/String;)V 
    flags: ACC_PUBLIC, ACC_STATIC 
    Code: 
     stack=2, locals=2, args_size=1 
     0: invokedynamiC#3, 0    // InvokeDynamiC#0:get:()Ljava/util/function/Supplier; 
     5: astore_1 
     6: getstatic  #4     // Field java/lang/System.out:Ljava/io/PrintStream; 

Hier können wir den invokedynamic Anruf sehen, die, wenn ich, von anonymer Instanz erstellt richtig verstehen Lieferantenschnittstelle An aufgerufenedynamic übergeben sind zwei Argumente, eines ist # 3. Das zweite Argument ist 0. Meine erste Frage ist also: Wofür steht 0?

Im Konstanten Pool steht # 3 für #3 = InvokeDynamiC#0:#27 // #0:get:()Ljava/util/function/Supplier;. Es gibt einen Verweis auf # 27 im konstanten Pool, aber keinen Verweis auf # 0. Meine zweite Frage ist: Was bedeutet # 0 hier?

Antwort

5

Die #0 (die Sie im Kommentar neben der aufgerufenen Dynamik sehen können) ist eigentlich ein Index in der BootstrapMethods Tabelle. Also die erste Frage, die 0 bezieht sich eigentlich auf #0. Und das wiederum ist der Index der BootstrapMethods-Tabelle. Dies stellt eine Verbindung zwischen dem Aufrufursprung invokedynamic und der Zielmethode her.

Wenn Sie mit javap -c -v FileName dekompilieren würden, sehen Sie den ganzen konstanten Pool. (Was ich nehme, hast du getan?). Hier finden Sie einen Hinweis auf #X MethodHandle #y:#z IDDL.bootstrapDynamic. Dies ist der Punkt, auf den die BootstrapMethods-Tabelle verweist. Das Handle, das die #0 verweist, sollte schließlich zu einer static bootstrapDynamic() Methode aufgelöst werden.

+0

Sie meinen '0: # 32 invokestatic java/lang/invoke/LambdaMetafactory.metafactory: (Ljava/lang/invoke/MethodHandles $ Suche; Ljava/lang/String; Ljava/lang/invoke/MethodType; Ljava/lang/invoke/MethodType; Ljava/lang/invoke/Methodenhandle; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite; 'aus' BootstrapMethods: '? Aber es ist eine Anweisung, kein Wert –

+1

@DmitryV. Welchen Wert erwartest du? –

+0

Ich kann 'InvokeDynamiC# 0: # 27' nur nicht interpretieren, wenn # 0 eine Referenz auf' # 32 invokestatic ..yadayada..' ist –