java泛型存在类型擦除,typetoken通过匿名子类在编译期捕获泛型信息并保留至运行时,从而安全获取实际类型参数,如list中的string。

Java 运行时无法直接获取 List<string></string> 这样的泛型类型,因为泛型在编译后会被擦除(type erasure)。但借助 Google Guava 的 TypeToken,可以**在编译期“捕获”泛型信息并保留到运行时**,从而安全地获取泛型参数。
为什么需要 TypeToken?
普通写法如 new ArrayList<string>().getClass()</string> 只能得到 ArrayList.class,丢失了 <string></string> 信息。而 TypeToken<list>>() {}</list> 利用匿名子类的 getGenericSuperclass(),让 JVM 在字节码中保留泛型结构,进而解析出实际类型参数。
基本用法:获取 List 的泛型元素类型
以获取 List<user></user> 中的 User 类型为例:
// 正确:用匿名子类“固化”泛型信息TypeToken<list>> token = new TypeToken<list>>() {};</list></list>Type elementType = token.getType(); // 整个 List<user> 类型</user>Type listType = token.getRawType(); // Class<list></list>Type[] typeArgs = ((ParameterizedType) elementType).getActualTypeArguments(); // [User]Class> elementClass = (Class>) typeArgs[0]; // User.class
通过 Auth0 Token Vault,代表已认证用户访问 Gmail、Slack、Google Calendar、GitHub 等第三方服务以及自定义 Auth0 连接。使用...
实用封装:提取泛型元素 Class
可封装成通用方法,避免每次手动强转:
public static <t> Class<t> getElementType(TypeToken extends Collection<t>> token) {</t></t></t> Type type = token.getType(); if (type instanceof ParameterizedType) { Type[] args = ((ParameterizedType) type).getActualTypeArguments(); if (args.length == 1 && args[0] instanceof Class) { return (Class<t>) args[0];</t> } } throw new IllegalArgumentException("无法解析泛型元素类型");}
调用:Class<user> clazz = getElementType(new TypeToken<list>>() {});</list></user>
注意事项与常见坑
-
必须用匿名子类语法:
new TypeToken<list>>() {}</list>—— 少了{}就只是普通泛型实例,无法保留类型信息 -
不能用于局部变量泛型推断:比如
TypeToken<list>> t = ...</list>中的T是未绑定的类型变量,运行时仍为Object -
嵌套泛型需逐层解析:如
List<map integer>></map>,需先取List的第一个参数(即Map<string integer></string>),再对它做二次解析 -
依赖 Guava:确保引入
com.google.guava:guava(≥20.0)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










