Sunday 8 June 2008

How to call private constructor/method from outside in Java

As you certainly know, one of the OOP’s features is encapsulation. Java has private keyword to specify encapsulated constructors, methods or attributes. These methods and attributes should not be accessible from the rest of the world (they are not part of the API) and Java doesn’t allow you to do that ordinarily.

You can however use Java reflections API to access any private method, field or constructor of any class and it’s really very simple task. Let’s assume we have got the following simple class:
public class Test {

private Test() {
System.out.println("private constructor has been called");
}

private void test() {
System.out.println("private test() method has been called");
}

}
The class has private constructor and method (notice that such class is worthless because there is no way how to ordinarily get or create instance of it). Now I’ll show you how to get instance of the class using Java reflections and call the private method:
public class Main {

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, SecurityException, NoSuchMethodException {

Class<Test> clazz = Test.class;

Constructor<Test> c = clazz.getDeclaredConstructor((Class[])null);
c.setAccessible(true); //hack
Test test = c.newInstance((Object[])null);

Method privateMethod = clazz.getDeclaredMethod("test", (Class[])null);
privateMethod.setAccessible(true); //hack
privateMethod.invoke(test, (Object[])null);
}

}
If you hadn’t called the setAccessible(true) method you would have got the java.lang.IllegalAccessException indicating that you call a method/constructor which is not meant to be called from outside.

Java reflections breaks OOP in many ways and you should very rarely use its “special” features like accessing private methods in your projects.

1 comment:

Anonymous said...

Perfect. Thank you!!