Sunday, February 14, 2010

Is 'private' really 'private'?

I've got the following Java class with private methods.

class ClassX {

private void methodX() {
System.out.println("methodX: this is private.");
}

private void methodY() {
System.out.println("methodY: this is private.");
}
}


How to invoke these methods from an outside class without modifying this code?
If you've studied Java, you might have learnt that it's impossible.

Truth is, you can access anything from anywhere.
Just use Reflection.

class Main {
public static void main(String[] args) throws Exception {
ClassX cx = new ClassX();
Method method = ClassX.class.getDeclaredMethod("methodX", null);
method.setAccessible(true);
method.invoke(cx, null);
}
}

All you have to do is to take the method using 'getDeclaredMethod', then set it as 'accessible' (previously it was not accessible since it was private). Now you can do any damn thing with it. How simple is it?

Still not enough? You can iterate through all declared methods in a class. (in case it is a compiled one and you don't already know what private methods are there)

Method[] ms = ClassX.class.getDeclaredMethods();
for (Method m: ms) {
System.out.println(m.toString()); // see what it is.
m.setAccessible(true);
m.invoke(cx, null); // invoking each method.
}

You can do the same thing for variables as well.

Is 'private' really 'private'? No.
Then how to make something really 'private'? Who knows?
That's not the important point here. If you don't know about reflection, then go ahead and learn it. Reflection is what enables real 'dependency injection' in Java.