Ever heard of reflection?
It’s a powerful Java technique that make it a possible for the JVM to manipulate objects the developer did not know about.
There’s an entire API devoted to it:
it is located under the java.lang.reflect
package.
For example, I once created a RPC web-services engine that could launch any methods of any class so long a the adequate class could be found on the classpath. It is not really hard to do.
But the true power of reflection lies within its ability to call non accessible methods from any code. Yes, reflection enables the developer to call private methods! How so?
Let’s take an example:
public class MyClass {
private void myPrivateMethod() {
...
}
}
As you know, under normal cicumstances, only instances of the MyClass
class are able to call the myPrivateMethod
method.
The following should show you the contrary:
public class ReflectionExample {
public void callPrivateMethod() throws Exception {
// Create a reference on the private method
Method myPrivateMethod = MyClass.class.getDeclaredMethod("myPrivateMethod");
// This make it possible to call a unaccessible method
myPrivateMethod.setAccessible(true);
// Create a new instance of my class
MyClass myClass = new MyClass();
// Invoke the method here
myPrivateMethod.invoke(myClass);
}
}
Et voila!
Instant private method call.
The real power lies in the line 9.
It effectively tells the JVM to ignore access rights.
Scary thought, no? Well, it is not:
all code lines above will throw a SecurityException
if the security manager denies them the right to execute.
So the code won’t ever run in a protected sandbox (such as Java Web Start or an applet).
The uses of such a strategy are endless:
- decoupling,
- inversion of control (how do you thing Spring manages to inject your resources?),
- architectural freedom relative to test (package visibility is no more mandatory),
- web services RPC,
- etc.
Any more ideas?