views:

533

answers:

2

I have a class that uses XML and reflection to return Objects to another class. Normally these objects are sub fields of an external object, but occasionally its something I want to generate on the fly. I've tried something like this but to no avail. I believe that's because JAVA won't allow you to access private methods for reflection.

Element node = outerNode.item(0);
String methodName = node.getAttribute("method");
String objectName = node.getAttribute("object");

if("SomeObject".equals(objectName))
  object = someObject;
else
  object = this;

method = object.getClass().getMethod(methodName,(Class[])null);

if the method provided is private it fails with a no such method. I could solve it by making the method public, or making another class to derive it from.

Long story short, I was just wondering if there was a way to access a private method via reflection.

+7  A: 

Use getDeclaredMethod() to get a private Method object and then use method.setAccessible() to allow to actually call it.

Toader Mihai Claudiu
The accepted answer is actually complete.
Toader Mihai Claudiu
+9  A: 

You can invoke private method with reflection. Modifying the last bit of the posted code:

method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
Object r = method.invoke(object);

There are a couple of caveats. First, getDeclaredMethod will only find method declared in the current Class, not inherited from supertypes. So, traverse up the concrete class hierarchy if necessary. Second, a SecurityManager can prevent use of the setAccessible method. So, it may need to run as a PrivilegedAction (using AccessController or Subject).

erickson
when I've done this in the past, I've also called method.setAccessible(false) after calling the method, but I have no idea if this is necessary or not.
shsteimer
No, when you set accessibility, it only applies to that instance. As long as you don't let that particular Method object escape from your control, it's safe.
erickson