I'm looking for a way to find out if an object x is an instance
of a generic type. For example List<String>.
Inspired by the Super-Type-Token idiom I can retrieve the java.lang.reflect.Type at runtime with follwing code
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class Test {
public static void main(String[] args) {
TypeReference<List<String>> ref = new TypeReference<List<String>>() {};
System.out.println(ref.getType());
System.out.println(ref.getType().getClass());
}
abstract static class TypeReference<T> {
private final Type type;
protected TypeReference() {
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
type = superclass.getActualTypeArguments()[0];
}
public Type getType() {
return type;
}
}
}
The output is
java.util.List<java.lang.String>
class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
How can I use this information for dynamic casting or type checking?
Background is I'm currently writing a heterogeneous type-safe container lib and want to add support for generic types https://bitbucket.org/mbeyene/jam
You must notice that you're using a parameterized type as type argument for TypeReference<T> instance. So you would need to cast it to ParameterizedType at the caller end, and get the raw type from that.
Then you can cast that rawtype to Class<?> type, and use Class#isInstance() method:
public static void main(String[] args) {
TypeReference<List<String>> ref = new TypeReference<List<String>>() {};
List<String> list = new ArrayList<String>();
Type rawType = ((ParameterizedType)ref.getType()).getRawType();
boolean listIsInstanceOfRawType = ((Class<?>)(rawType)).isInstance(list));
System.out.println(listIsInstanceOfRawType); // true
}
Note that, you can't check instanceof against a parameterized type - List<String> or List<Integer>, as that doesn't make sense. Both of them are nothing but List at runtime. What I mean is:
List<String> list = new ArrayList<String>();
System.out.println(list instanceof List<String>); // Won't compile
System.out.println(list instanceof List); // You've to do this.
// The reason is, this is true
System.out.println(new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass()); // true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With