2

I am trying to figure out how to use reflection. I have set up 2 classes one has basic validation for numbers

public class Reflectee {

    String str;

    public Reflectee(String str){
        this.str=str;
    }

    public Reflectee(){

    }
    public boolean doSomething(String str){
        boolean flag=true;
        try{
            Integer.parseInt(str);
        }catch (NumberFormatException e){
            flag=false;
        }
        return flag;
    }
}

and then I have created a class that is going to use reflection to invoke doSomething method.

public class Reflector {

    private String str="22";

    public boolean reflect(){
        Reflectee r=new Reflectee();
        Class clazz=r.getClass();
        boolean b=false;
        try {
            Method m=clazz.getDeclaredMethod("doSomething",String.class);
            b=(Boolean)m.invoke(this,str); //Exception is here
        } catch (NoSuchMethodException | SecurityException |
                IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
    }
}

I get an exception when I am trying to invoke a method the exception is

java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.app.example2.Reflector.reflect(Reflector.java:16)
    at com.app.example2.test.Reflector_UT.test(Reflector_UT.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

I am sure that I am missing something minor. Any ideas what is wrong?

Thanks

1 Answer 1

6

problem is on the following line

 b=(Boolean)m.invoke(this,str); //Exception is here

you have to invoke method on the Reflectee object rather than this(Reflector object)

 b=(Boolean)m.invoke(r,str); //Exception is here
Sign up to request clarification or add additional context in comments.

3 Comments

That works however when I replace b=(Boolean)m.invoke(this,str); with b=(Boolean)m.invoke(clazz,str); I still get an exception, why?
m.invoke(r, str) is equivalent to r.doSomething(str). You cannot invoke doSomething method without an object of Relfectee class. Now m.invoke(clazz, str) is equivalent to clazz.doSomething(str) which obviously is wrong
Just an improvement suggestion on your comment: Using explicit variables would be more of a help for readers with less experience

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.