2016-07-28 5 views
3

J'ai cette classe, et je la compile.Java bytecode, java Fournisseur et argument invokedynamique

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()); 
    } 
} 

Puis, en essayant de regarder dans c'est bytecode, je me suit début de public static void main fonction:

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; 

Ici, nous pouvons voir l'appel invokedynamic, qui, si je comprends bien, crée par exemple anonyme Interface fournisseur Passé à invokedynamic sont deux arguments, l'un est # 3. Le deuxième argument est 0. Donc, ma première question est: qu'est-ce que 0 représente ici?

Dans le groupe constant n ° 3, correspond à #3 = InvokeDynamiC#0:#27 // #0:get:()Ljava/util/function/Supplier;. Il y a une référence à # 27 dans le pool constant, mais pas de référence à # 0. Ma deuxième question est: qu'est-ce que le 0 représente ici?

Répondre

5

Le #0 (que vous pouvez voir dans le commentaire en regard de l'invokedynamic) est en fait un index dans la table BootstrapMethods. Donc, la première question, le 0 fait référence à #0. Et cela à son tour est l'index de la table BootstrapMethods. Ce qui fournit un lien entre l'origine de l'appel invokedynamic et la méthode ciblée.

Si vous souhaitez décompiler avec javap -c -v FileName, vous verrez l'ensemble du pool de constantes. (Ce que je suppose que vous avez fait?). Vous devriez trouver ici une référence à #X MethodHandle #y:#z IDDL.bootstrapDynamic. C'est le point auquel la table BootstrapMethods est liée. Le descripteur associé aux liens #0 doit éventuellement être résolu en une méthode static bootstrapDynamic().

+0

Vous voulez dire 0: # 32 invokestatic java/lang/invoke/LambdaMetafactory.metafactory: (Ljava/lang/invoke/MethodHandles $ Recherche; Ljava/lang/String; Ljava/lang/invoke/MethodType; Ljava/lang/invoquer/MethodType; Ljava/lang/invoquer/MethodHandle; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite; 'de' BootstrapMethods: '? Mais c'est une instruction, pas de valeur –

+1

@DmitryV. Quelle valeur attendez-vous? –

+0

Je ne peux pas interpréter 'InvokeDynamiC# 0: # 27' dans le cas où # 0 est une référence à' # 32 invokestatic ..yadayada..' –