Java – why is implicit conversion effective when reflection casting throws an exception?
Assume the following codes:
@SuppressWarnings("unchecked") public static <T> T implicitCaster(Class<T> cls,Object o) { return (T) o; } public static <T> T reflectionCaster(Class<T> cls,Object o) { return cls.cast(o); }
The code works as expected in both cases, but there are the following exceptions in the primitive:
public static void main(String[] args) { System.out.println(implicitCaster(int.class,42)); System.out.println(reflectionCaster(int.class,42)); }
The first call works as expected, but the second one throws a Java lang.ClassCastException.
Is this a corner case without considering automatic packing? Or is it impossible for reflective casting to provide automatic packing in this case? Or are there other reasons for this inconsistency?
Edit: call this code to work as expected:
public static void main(String[] args) { System.out.println(implicitCaster(Integer.class,42)); System.out.println(reflectionCaster(Integer.class,42)); }
Solution
This is because of type erasure
At run time, there are no generic type parameters Invalid argument to convert object to generic type (that's why you get a warning from an unchecked actor)
Therefore, your first line of auto boxing 42 passes the object to the method Then the function returns the object, which will be passed to system out. println.
Your second call calls the cast method of the int base type This throws an exception because the object cannot be converted to a base type (auto boxing is a pure compile time function, so it doesn't help)
An error occurs when cast() checks isinstance() verifies that the transformation is valid
Documentation for isinstance() say:
(key supplement)
Your editing is valid because you no longer use basic types In both cases, the compiler will automatically box 42 so that it can be passed as an object
As before, the first call is invalid The second call verifies that the boxed integer is actually an instance of the integer class, and then returns it