2016-01-13 173 views
2

MethodHandle的Java文档说私有方法应该通过findSpecial.But调用,在以下示例中我可以通过findVirtual调用它。使用findVirtual调用的方法处理私有方法

有人请解释我在这里想念什么?

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

回答

1

你能因为你有机会获得来自同一类,其中main运行 尝试运行这段代码的私有方法来调用它:

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

要调用私有方法,你应该使用反射API和更改方法访问类型:

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

有没有一种方法可以从PrivateClassMethodLookupTest调用Inner.m? MethodHandles.lookup() .findSpecial(....)不起作用 – nantitv

+1

它是可行的使用反射API 方法declaredMethod = PrivateClassMethodLookupTest.Inner.class.getDeclaredMethod(“m”); declaredMethod.setAccessible(true); MethodHandle mh = MethodHandles.lookup()。unreflect(declaredMethod); mh.invoke(new PrivateClassMethodLookupTest.Inner()); – D0dger

+0

你知道为什么findSpecial不可能吗? – nantitv

相关问题