您的位置:首页 > 其它

Guava中的TypeToken,解决泛型运行时类型擦除的问题

2017-06-14 10:56 295 查看

关于对于Type的理解

泛型是一种类型

关于Type,是一个标示接口,该标示接口描述的意义是代表所有的类型

public interface Type {
}


Type的分类

Class<T>
ParameterizedType  泛型
......


泛型的结构

public Person<T> {

}
public interface ParameterizedType extends Type {
Type[] getActualTypeArguments();  <T>
Type getRawType();                Person
Type getOwnerType();              Person<T>
}


参数的传递

第一种情况

ArrayList<E>
ArrayList<Person> al = new ArrayList<Person>();  在执行该代码的时候就把Person传递给E了


* 第二种情况


public interface BaseDao<T>{

}

public class BaseDaoImpl<T> implements BaseDao<T>{
private Class<?> clazz;

public BaseDaoImpl() {
if (clazz == null) { // 获取泛型的Class对象
clazz = ((Class<?>) (((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
}
}

}

public class PersonDaoImpl extends BaseDaoImpl<Person>{}


关于Guava中的TypeToken,解决泛型运行时类型擦除的问题

guava反射包中的TypeToken类是用来解决java运行时泛型类型被擦除的问题的,有点不好理解,我们通过一个例子来认识什么是泛型的运行时类型擦除。

ArrayList<String> stringList = Lists.newArrayList();
ArrayList<Integer> intList = Lists.newArrayList();
System.out.println("intList type is " + intList.getClass());
System.out.println("stringList type is " + stringList.getClass());
System.out.println(stringList.getClass().isAssignableFrom(intList.getClass()));


上面的代码我们声明了两个泛型的ArrayList类型,一个泛型的类型参数是String,另外一个是Integer;然后我们输出了两个泛型的Class,并输出两个list的类型是否是同一个list。我们看下输出的结果:

intList type is class java.util.ArrayList
stringList type is class java.util.ArrayList
true


前两个输出都是java.util.ArrayList,而第三个输出竟然是true,也就是认为stringList和intList的类型是一样的。这就是所谓的泛型类型擦除。运行时我们不知道泛型类型的类型参数是什么了。

TypeToken可以解决这个问题,请看下面代码:

TypeToken<ArrayList<String>> typeToken = new TypeToken<ArrayList<String>>() {};
TypeToken<?> genericTypeToken = typeToken.resolveType(ArrayList.class.getTypeParameters()[0]);
System.out.println(genericTypeToken.getType());


注意上面第一行代码使用了一个空的匿名类。第二行使用了resolveType方法解析出泛型类型,第三行代码打印出泛型类型,输出是:

class java.lang.String


可以看出TypeToken解析出了泛型参数的具体类型。

TypeToken的方法列表如下:

方法 描述

getType() 获得包装的java.lang.reflect.Type.

getRawType() 返回大家熟知的运行时类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: