IllegalAccessException on using reflection

后端 未结 5 781
情书的邮戳
情书的邮戳 2020-12-09 18:05

I was trying to learn reflection and I came across this IllegalAccessException. Please see the following code:

public class ReflectionTest
{
      public sta         


        
5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-09 18:57

    I suspect you should use getDeclaredMethod (among other issues). I don't bother to remember Reflection API details (they're for the compiler!), but in your case compare your code with that produced by dp4j:

    $ javac -Averbose=true -All -cp dp4j-1.2-SNAPSHOT-jar-with-dependencies.jar ReflectionTest.java 
    ReflectionTest.java:6: Note: 
    import java.util.*;
    
    public class ReflectionTest {
    
    public ReflectionTest() {
        super();
    }
    
    @com.dp4j.Reflect()
    public static void main(String[] args) throws java.lang.ClassNotFoundException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException, java.lang.InstantiationException, java.lang.IllegalArgumentException {
        final java.lang.reflect.Constructor hashSetConstructor = Class.forName("java.util.HashSet").getDeclaredConstructor();
        hashSetConstructor.setAccessible(true);
        Set myStr = (.java.util.Set<.java.lang.String>)hashSetConstructor.newInstance();
        final java.lang.reflect.Method addWithEMethod = Class.forName("java.util.Set").getDeclaredMethod("add", .java.lang.Object.class);
        addWithEMethod.setAccessible(true);
        addWithEMethod.invoke(myStr, new .java.lang.Object[1][]{"obj1"});
        final java.lang.reflect.Method iteratorMethod = Class.forName("java.util.Set").getDeclaredMethod("iterator");
        iteratorMethod.setAccessible(true);
        Iterator itr = (.java.util.Iterator)iteratorMethod.invoke(myStr);
        final java.lang.reflect.Method hasNextMethod = Class.forName("java.util.Iterator").getDeclaredMethod("hasNext");
        hasNextMethod.setAccessible(true);
        final java.lang.reflect.Method printlnWithbooleanMethod = Class.forName("java.io.PrintStream").getDeclaredMethod("println", .java.lang.Boolean.TYPE);
        printlnWithbooleanMethod.setAccessible(true);
        printlnWithbooleanMethod.invoke(System.out, new .java.lang.Object[1][]{hasNextMethod.invoke(itr)});
    }
    

    }

        public static void main(String[] args)
                           ^
    ...
    
    $ java ReflectionTest
    true
    

    The only change you need to do is annotate your main method with @com.dp4j.Reflect:

    $ vim ReflectionTest.java
    import java.util.*;
    
    public class ReflectionTest
    {
            @com.dp4j.Reflect
            public static void main(String[] args)
            {
                    Set myStr = new HashSet();
                    myStr.add("obj1");
                    Iterator itr = myStr.iterator();
                    // Method mtd = itr.getClass().getMethod("hasNext");
                    System.out.println(itr.hasNext());
            }
    }
    

    NB: this works only with dp4j-1.2-SNAPSHOT (I've just added suport for it). If you don't use Maven, download the jar from here. You find the test case with your problem here.

提交回复
热议问题