I found a very interesting phenomenon in Java type reflection when building an Android app.
I’m trying to build a common mechanism to serialize Enum into integer when writing it into database. To make it more flexible so I fetch the value type dynamically by using reflection. So I have the following code to check whether the value to be written is an enumeration:
|
|
I built the converters into a responsibility chain
. The converter is applied only when match
method returns true.
In the converter, I check the type with isEnum
method. I expects the method yields true when the value is a enumeration. But later I found it doesn’t work as expected. And the behavior of this method is really confusing!
Here is how it works:
|
|
Due to the implementation of Java Enumeration, the definition of enumeration value could be understood as the following code:
|
|
So the value FULL
has a different type than ServiceStatus
as I expected, the type of FULL
is actually a subclass of ServiceStatus
. And the enumeration value FULL
is a singleton instance of the anonymous sub-class.
The the most unexpected behavior is that the isEnum
method only returns true on Enumeration class itself, not its subclass!
To resolve this issue gracefully, I changed my implementation a little bit. Here is the updated implementation:
|
|
I uses isAssignableFrom
to check whether value is the subclass of Enum or could be casted into Enum. I found this approach solved the issue gracefully.