2015-03-19 60 views
0

我試圖通過思考得到包私有方法/領域是這樣的:如何使用ReflectionUtils獲取包私有方法/字段?

for (Method m : getAllMethods(cls, withModifier(Modifier.STATIC))){ 

,但它是空的。有沒有什麼辦法可以通過私有包進行過濾?

+0

你只想要'private static'方法嗎?或者所有的「私人」方法?另外,你可以發佈你正在嘗試使用反射的類的方法簽名嗎? – JNYRanger 2015-03-22 20:10:11

+0

包私有和私有訪問修飾符是**不**是同一件事。包私人是指那些不使用訪問修飾符;也稱爲Java中的默認修飾符。 – hfontanez 2015-03-22 20:43:56

+0

在我以前的評論中,我的意思是說私有包和** STATIC **不是同一件事。 – hfontanez 2015-03-23 11:56:41

回答

2
for (Method m : getAllMethods(cls, ReflectionUtils.getAllMethods(cls, Predicates.not(withModifier(Modifier.PRIVATE)), Predicates.not(withModifier(Modifier.PUBLIC)), Predicates.not(withModifier(Modifier.PROTECTED))))) 
{ 
    // DO STUFF 
} 

我用下面的方法來測試上述。 MyClass包含5種方法;爲每個訪問修飾符和一個靜態:

public class MyClass 
{ 

    public void method1() 
    { 
     System.out.println("method1() invoked"); 
    } 

    private void method2() 
    { 
     System.out.println("method2() invoked"); 
    } 

    protected void method3() 
    { 
     System.out.println("method3() invoked"); 
    } 

    void method4() 
    { 
     System.out.println("method4() invoked"); 
    } 

    public static void method5() 
    { 
     System.out.println("method5() invoked"); 
    } 
} 

我的測試類:

import static org.reflections.ReflectionUtils.withModifier; 

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.util.Set; 

import org.reflections.ReflectionUtils; 

import accessmodifier.bar.MyClass; 

import com.google.common.base.Predicates; 

public class ReflectionTest 
{ 

    public static void main(String[] args) 
    { 
     Class<MyClass> cls = MyClass.class; 
     Set<Method> privateMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PRIVATE)); 
     Set<Method> protectedMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PROTECTED)); 
     Set<Method> publicMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PUBLIC)); 
     Set<Method> defaultMethods = ReflectionUtils.getAllMethods(cls, Predicates.not(withModifier(Modifier.PRIVATE)), Predicates.not(withModifier(Modifier.PUBLIC)), Predicates.not(withModifier(Modifier.PROTECTED))); 
     Set<Method> staticMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.STATIC)); 

     System.out.println("Private Methods"); 
     for (Method m : privateMethods) 
      System.out.println(m.getName()); 

     System.out.println("\nProtected Methods"); 
     for (Method m : protectedMethods) 
      System.out.println(m.getName()); 

     System.out.println("\nPublic Methods"); 
     for (Method m : publicMethods) 
      System.out.println(m.getName()); 

     System.out.println("\nPackage-Private Methods"); 
     for (Method m : defaultMethods) 
      System.out.println(m.getName()); 

     System.out.println("\nStatic Methods"); 
     for (Method m : staticMethods) 
      System.out.println(m.getName()); 
    } 
} 

程序輸出

Private Methods 
method2 

Protected Methods 
method3 

Public Methods 
method1 
method5 

Package-Private Methods 
method4 

Static Methods 
method5 

UPDATE 如果你想能夠調用一個可訪問的方法(比如package-private),你將不得不像th一樣是:

 m.setAccessible(true); // bypass access 
     try 
     { 
      m.invoke(new MyClass(), null); // invoke method (you have to know parameter types and pass them if needed. Use *Method.getParameter...()* methods for that. 
     } 
     catch (IllegalAccessException | IllegalArgumentException 
       | InvocationTargetException e) 
     { 
      e.printStackTrace(); 
     } 
2

若要檢索您需要查詢所有方法和排除與publicprotectedprivate修飾這些方法包專用方法:

import org.reflections.ReflectionUtils; 
import java.lang.reflect.Field; 
import java.lang.reflect.Method; 
import java.lang.reflect.Modifier; 
import java.util.Set; 

... 

Set<Method> allMethods = ReflectionUtils.getAllMethods(Foo.class); 
for (Method method : allMethods) { 
    boolean isPackagePrivate = !(Modifier.isPrivate(method.getModifiers()) || Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers())); 

    if (isPackagePrivate) { 
     System.out.println("package private method: " + method.getName()); 
    } 
} 

相同的字段:

Set<Field> allFields = ReflectionUtils.getAllFields(Foo.class); 
for (Field field : allFields) { 
    boolean isPackagePrivate = !(Modifier.isPrivate(field.getModifiers()) || Modifier.isPublic(field.getModifiers()) || Modifier.isProtected(field.getModifiers())); 

    if (isPackagePrivate) { 
     System.out.println("package private field: " + field.getName()); 
    } 
} 

com.google.guava:guava提供了一個更方便以及使用InvokableMethod(或Constructor)附近的更易讀的API:

import com.google.common.reflect.Invokable 

... 

Invokable<?, Object> invokable = Invokable.from(method); 
if (invokable.isPackagePrivate()) { 
    System.out.println("package private method: " + method.getName()); 
} 
+1

包私有是那些不公開,私人或**保護**。基本上,包私有實體沒有訪問修飾符。如果在Foo類中包含受保護的方法,則測試用例會失敗。 – hfontanez 2015-03-22 22:19:02

+0

是的 - 當然你是對的。忘記排除'protected'修飾符。編輯答案。 – fateddy 2015-03-22 22:32:24

+0

我會包含一個更完整的類,其中包含不同的訪問修飾符。儘可能多的路徑以確保你的解決方案是穩定的。我編輯你的課程以包含更多方法。 – hfontanez 2015-03-22 22:38:39