2016-01-13 84 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