guava反射TypeToken解决泛型运行时类型擦除的问题
2015-05-11 16:19
363 查看
guava反射包中的TypeToken类是用来解决java运行时泛型类型被擦除的问题的,有点不好理解,我们通过一个例子来认识什么是泛型的运行时类型擦除。
上面的代码我们声明了两个泛型的ArrayList类型,一个泛型的类型参数是String,另外一个是Integer;然后我们输出了两个泛型的Class,并输出两个list的类型是否是同一个list。我们看下输出的结果:
前两个输出都是java.util.ArrayList,而第三个输出竟然是true,也就是认为stringList和intList的类型是一样的。这就是所谓的泛型类型擦除。运行时我们不知道泛型类型的类型参数是什么了。
TypeToken可以解决这个问题,请看下面代码:
注意上面第一行代码使用了一个空的匿名类。第二行使用了resolveType方法解析出泛型类型,第三行代码打印出泛型类型,输出是:
可以看出TypeToken解析出了泛型参数的具体类型。
TypeToken的方法列表如下:
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() | 返回大家熟知的运行时类 |
getSubtype(Class<?>) | 返回那些有特定原始类的子类型。举个例子,如果这有一个Iterable并且参数是List.class,那么返回将是List。 |
getSupertype(Class<?>) | 产生这个类型的超类,这个超类是指定的原始类型。举个例子,如果这是一个Set并且参数是Iterable.class,结果将会是Iterable。 |
isAssignableFrom(type) | 如果这个类型是 assignable from 指定的类型,并且考虑泛型参数,返回true。List<? extends Number>是assignable from List,但List没有. |
getTypes() | 返回一个Set,包含了这个所有接口,子类和类是这个类型的类。返回的Set同样提供了classes()和interfaces()方法允许你只浏览超类和接口类。 |
isArray() | 检查某个类型是不是数组,甚至是<? extends A[]>。 |
getComponentType() | 返回组件类型数组。 |
相关文章推荐
- Java反射TypeToken解决泛型运行时类型擦除问题
- Java反射TypeToken解决泛型运行时类型擦除问题
- Guava中的TypeToken,解决泛型运行时类型擦除的问题
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
- 利用gson处理Java反射TypeToken泛型运行时类型擦除
- GSON TypeToken 解决泛型问题
- GSON TypeToken 解决泛型问题
- 解决C#中dynamic类型作为泛型参数的反射问题
- 如何在Access中参数化日期类型,以解决Data type mismatch in criteria expression的问题
- Gson通过借助TypeToken获取泛型参数的类型的方法
- SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题
- 解决Asp.net 程序在 IIS 5.1 上运行不支持转换Decimal类型小数点的问题
- 以不同用户身份运行程序,/savecred只需要输入一次密码(GetTokenByName取得EXPLORER.EXE的令牌,然后调用CreateProcessAsUser,而且使用LoadUserProfile解决另存文件的问题)good
- Gson通过借助TypeToken获取泛型参数的类型的方法
- 容易被忽略的细节(2):使用泛型类和泛型方法解决【动态类型】问题
- Gson通过借助TypeToken获取泛型参数的类型的方法(转)
- QT 信号槽connect中解决自定义数据类型或数组作为函数参数的问题——QT qRegisterMetaType 注册MetaType——关键:注册自定义数据类型或QMap等容器类