0

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?

1
  • You have to create an instance the class you want to invoke methode on: m1.invoke(clazz.newInstance()); Commented Feb 16, 2018 at 13:45

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I put this as the parameter and it worked flawlessly, thanks for your input!
2

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".

1 Comment

Thanks, I realised that I have to put the class that I'm currently working on as the object in the first parameter. Must be tired today, good thing it's friday. Cheers!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.