如何使用ReflectionUtils获取包私有方法/字段?

时间:2015-03-19 10:58:54

标签: java google-reflections

我试图通过像这样的反射来获取包私有方法/字段:

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

但它是空的。有没有办法按包私有过滤?

2 个答案:

答案 0 :(得分: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使用Invokable围绕Method(或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 :(得分: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

<强>更新 如果您希望能够调用可访问的方法(例如package-private),则必须执行以下操作:

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