Search code examples
javareflections

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


I tried to get package private methods/field via Reflections like this:

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

but it is empty. Is there any way to filter by package private?


Solution

  • 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
    }
    

    I used the following to test the above. MyClass contain 5 methods; one for each access modifier and one static:

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

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

    PROGRAM OUTPUT

    Private Methods
    method2
    
    Protected Methods
    method3
    
    Public Methods
    method1
    method5
    
    Package-Private Methods
    method4
    
    Static Methods
    method5
    

    UPDATE If you want to be able to invoke an accessible method (such as package-private), you will have to something like this:

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