Hi, everyone!
Today I would like to talk a little about reflection api and some interesting tricks we can do with it.
Basically, reflection allows us to introspect the object's structure during the runtime.
With the help of reflection we can:
- obtain the information about the methods/fields of the object
- obtain the information about superclass/interfaces that the object implements
- obtain the value of the data fields
- invoke the methods of the object dynamically
While in general I believe that the reflection shouldn't be vastly used in a properly designed Object Oriented program, sometimes we just can't live without this very powerful feature. From my experience the reflection based APIs are extensively used in different frameworks when we just don't have any information about the classes that will be used...
In this post I'll try to show some less known usages of the reflection API.
So, here we go :)
1. Instanceof with reflection
We will mimic the well known instanceof operator's behavior with the help of reflection:
The Class java.lang.Number is the common ancestor for Integer, Float, Double and other so-called wrapper classes
So we expect that the following code will produce 'true' twice:
Ok, but we knew that i is castable to Number, so it's not a big deal...
Now how about checking the String:
One could expect that this code would print 'false'. But in fact we can't even compile this code. The error is :
Inconvertible types; can't cast java.lang.String to java.lang.Number
So we can't fool the java compile with obviously false expression.
We can however upcast our String to Object and this code will run as expected.
The output is 'false'
Now lets see how the things can be done with the help of reflection:
Class "java.lang.Class" contains meta information about the object, this is our key to reflection APIs.
We will use its "isAssignableFrom" method that behaves exactly like 'instanceof' operator but makes it regardless the called classes. The method called on the class A will return true iff the parameter (which is also a java.lang.Class) is a successor of class A (or class A itself).
Example:
>>true - because Integer is a subclass of Number
>>false - because String is not a subclass of Number
>>true - because Number can be assigned to Number (upcasted).
>> false - because String is not a subclass of Number
As we see we the same result could be achieved with 'instanceof'.
But this time we don't need the casting (!); and since any object has a getClass() method, we don't need any information about the object we're going to check. This is impossible if we would chose the 'instanceof' approach:
Example:
2. Accessing the private data of the object.
OK, this sounds like a dirty trick, since it seems to break the encapsulation. But sometimes we need to know what is an internal structure of the class.
So how we can do that?
Imagine we have a fairly simple class A defined like this:
Using the traditional object oriented approach we just don't have a way to modify or even read the value of the field foo outside the class A!
So what should we do?
Let's use reflection :)
The problem is that the field is private therefore the program produces an exception during the runtime:
java.lang.IllegalAccessException: Class Test can not access a member of class A with modifiers "private"
So we have to slightly modify the program. We will say to the java runtime environment: "Its ok, I know that I can access this variable"
The program will look like this:
Now the program will run perfectly and print out the value of "foo" field as expected.
Of course its possible to modify the property:
Now the output would be:
5
10
Thats all, hope you found this short article interesting!
Friday, April 2, 2010
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment