2016-01-13 7 views
2

Java doc de MethodHandle dit que la méthode privée devrait invoquer via findSpecial.But dans l'exemple suivant je suis capable de l'invoquer via findVirtual.Methodhandle méthode privée appelée using findVirtual

Quelqu'un pourrait-il expliquer ce qui me manque ici?

import java.lang.invoke.MethodHandles; 
import java.lang.invoke.*; 

import java.lang.invoke.MethodType; 

public class PrivateClassMethodLookupTest{ 
    public static void main(String[] args) throws Throwable{ 
    new PrivateClassMethodLookupTest().m(); 
    MethodHandle mh = MethodHandles.lookup() 
       .findVirtual(PrivateClassMethodLookupTest.class, "m", MethodType.methodType(void.class)); 
     mh.invoke(new PrivateClassMethodLookupTest()); 
    } 

    private void m() { System.out.println("in m");} 
} 

Répondre

1

Vous en mesure d'invoquer parce que vous avez accès à des méthodes privées de la même classe, où main est en cours d'exécution Essayez exécuter ce code:

package com.company; 

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

public class PrivateClassMethodLookupTest { 
    public static void main(String[] args) throws Throwable { 
     new PrivateClassMethodLookupTest.Inner().m(); 
     MethodHandle mh = MethodHandles.lookup() 
       .findVirtual(PrivateClassMethodLookupTest.Inner.class, "m", MethodType.methodType(void.class)); 
     mh.invoke(new PrivateClassMethodLookupTest.Inner()); 
    } 

    static class Inner { 
     private void m() { 
      System.out.println("in m"); 
     } 
    } 
} 

Pour appeler des méthodes privées, vous devez utiliser l'API de réflexion et changer le type d'accès à la méthode:

package com.company; 

import java.lang.invoke.MethodHandle; 
import java.lang.invoke.MethodHandles; 
import java.lang.reflect.Method; 

public class PrivateClassMethodLookupTest { 
    public static void main(String[] args) throws Throwable { 
     new PrivateClassMethodLookupTest.Inner().m(); 
     Method declaredMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod("m"); 
     declaredMethod.setAccessible(true); 
     MethodHandle mh = MethodHandles.lookup().unreflect(declaredMethod); 
     mh.invoke(new PrivateClassMethodLookupTest.Inner()); 
    } 

    static class Inner { 
     private void m() { 
      System.out.println("in m"); 
     } 
    } 
} 
+0

Existe-t-il un moyen d'appeler Inner.m à partir de PrivateClassMethodLookupTest? MethodHandles.lookup() .findSpecial (....) ne fonctionne pas – nantitv

+1

Il est possible d'utiliser la réflexion API Méthode déclaréeMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod ("m"); declareMethod.setAccessible (true); MethodHandle mh = MethodHandles.lookup(). Unreflect (méthode déclarée); mh.invoke (new PrivateClassMethodLookupTest.Inner()); – D0dger

+0

Savez-vous pourquoi ce n'est pas possible avec findSpecial? – nantitv