Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke an abstract method by reflection

I have a class SomeTaskManager with an abstract method runATask. I want to execute the runATask method via reflection, this is my code : what am I missing?

SomeTaskManager pm= (SomeTaskManager)context.getSomeTaskManager(); 
Class c = Class.forName( pm.getClass().getName() ); 

Method[] allMethods = c.getDeclaredMethods();

for (Method m : allMethods) {
    if (!m.getName().equals("runATask")) {
        continue;
    }
    m.invoke( c ,new Object[] { someParam, null, 1});
    break;
}  

I'm getting this errors

java.lang.IllegalArgumentException: object is not an instance of the class
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at de.vogella.android.downloadmanager.DownloadManagerActivity.riflesso(DownloadManagerActivity.java:250)
at de.vogella.android.downloadmanager.DownloadManagerActivity.onCreate(DownloadManagerActivity.java:68)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
at android.app.ActivityThread.access$1500(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3835)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
like image 298
Zorb Avatar asked May 08 '26 15:05

Zorb


2 Answers

java.lang.IllegalArgumentException: object is not an instance of the class
    at java.lang.reflect.Method.invoke(Method.java:507)

Aha, here

m.invoke(c, new Object[] { someParam, null, 1});

you're passing the Class instead of an instance of it. You need to pass pm (the concrete instance) to it instead:

m.invoke(pm, new Object[] { someParam, null, 1});

This problem would likely be spotted sooner by just reading the code if you used full and self-documenting variable names instead of nothing-saying abbreviations. I'd suggest to work on that as well.


Unrelated to the concrete problem, the following line

Class c = Class.forName( pm.getClass().getName() ); 

can be simplified as follows

Class c = pm.getClass();
like image 107
BalusC Avatar answered May 11 '26 06:05

BalusC


Use getMethods instead of getDeclaredMethods. The getDeclaredMethods() method doesn't return those methods which are inherited but getMethods() returns both declared and inherited.

like image 27
khill Avatar answered May 11 '26 04:05

khill



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!