您如何使用 ReflectionUtils 获取包私有 methods/fields?

How do you use ReflectionUtils to get package private methods/fields?

我试过像这样通过 Reflections 获取私有包 methods/field:

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

但它是空的。有什么方法可以按包私有过滤吗?

要检索包私有方法,您需要查询所有方法并使用 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());
}
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");
    }
}

我的测试class:

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