Reputation: 81
I recently had to use reflection to access some private methods and fields in a superclass. This is how it looked before I started using reflection:
processSecondPassesOfType(PkDrivenByDefaultMapsIdSecondPass.class);
processSecondPassesOfType(SetSimpleValueTypeSecondPass.class);
processSecondPassesOfType(CopyIdentifierComponentSecondPass.class);
processFkSecondPassInOrder();
processSecondPassesOfType(CreateKeySecondPass.class);
processSecondPassesOfType(SecondaryTableSecondPass.class);
Now I have to invoke the private method that I have acquired through reflection:
Class<?> clazz = Class.forName("org.hibernate.cfg.Configuration");
inSecondPass = true;
Method m1 = clazz.getDeclaredMethod("processSecondPassesOfType", Class.class);
m1.setAccessible(true);
m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);
When I try to run this, I get the following error:
java.lang.IllegalArgumentException: object is not an instance of declaring class
So how do I invoke a method with non-object parameters using reflection?
Upvotes: 0
Views: 1748
Reputation: 2228
m1.invoke(PkDrivenByDefaultMapsIdSecondPass.class);
When methods are invoked with java.lang.reflect.Method.invoke()
, the first argument is the object instance on which this particular method is to be invoked. (If the method is static, the first argument should be null.) Subsequent arguments are the method's parameters.
Hence, if the invoked method is static then invoke call would be;
m.invoke(null, methodArguments);
If the invoked method is not static then invoke call would be;
m.invoke(objectOnWhichMethodCalled, methodArguments);
If the underlying method throws an exception, it will be wrapped by an java.lang.reflect.InvocationTargetException
. The method's original exception may be retrieved using the exception chaining mechanism's InvocationTargetException.getCause()
method.
Upvotes: 2
Reputation: 140417
Unless this is a static method - you need instance to invoke on.
In normal code, you do:
foo.bar(x, y, z);
to invoke bar()
on foo
.
With reflection, logic is a somehow reversed, as you go:
handleToBar = ...
handleToBar.invoke(foo, x, y, ...
In other words: you can't invoke a non-static method "in thin air". You have to provide some object to invoke on.
And of course, the usual disclaimers: A) reflection is "evil" B) only use it if you absolutely have to and then C) know what you are doing and D) avoid calling things that are private - those are implementation detail and subject to change. Which you will only find out at runtime, because A) reflection is "evil".
Upvotes: 2