package com.owlike.genson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import com.owlike.genson.reflect.TypeUtil;
/**
* This class is a holder for generic types so we can work around type erasure. You can read <a
* href="http://gafter.blogspot.fr/2006/12/super-type-tokens.html">this blog post</a> who explains a
* bit more in details what it is about. For example if you want to use at runtime a
* List<Integer> :
* <p/>
* <pre>
* GenericType<List<Integer>> genericType = new GenericType<List<Integer>>() {
* };
* List<Integer> listOfIntegers = new Genson().deserialize("[1,2,3]", genericType);
*
* // if you want to get the standard java.lang.reflect.Type corresponding to List<Integer> from
* // genericType
* Type listOfIntegersType = genericType.getType();
* // listOfIntegersType will be an instance of ParameterizedType with Integer class as type argument
* </pre>
*
* @param <T> the real type
* @author eugen
*/
public abstract class GenericType<T> {
private final Type type;
private final Class<T> rawClass;
@SuppressWarnings("unchecked")
protected GenericType() {
Type superType = getClass().getGenericSuperclass();
if (superType instanceof Class<?>) {
throw new IllegalArgumentException("You must specify the parametrized type!");
}
type = ((ParameterizedType) superType).getActualTypeArguments()[0];
rawClass = (Class<T>) TypeUtil.getRawClass(type);
}
private GenericType(Class<T> rawClass) {
this.type = rawClass;
this.rawClass = rawClass;
}
@SuppressWarnings("unchecked")
private GenericType(Type type) {
this.type = type;
this.rawClass = (Class<T>) TypeUtil.getRawClass(type);
}
public static <T> GenericType<T> of(Class<T> rawClass) {
return new GenericType<T>(rawClass) {
};
}
public static GenericType<Object> of(Type type) {
return new GenericType<Object>(type) {
};
}
public Type getType() {
return type;
}
public Class<T> getRawClass() {
return rawClass;
}
}