如何用Java泛型实现通用getter方法,解决返回值类型不匹配编译报错?
问题原因
Java泛型采用编译期类型擦除机制,代码中你虽然通过if (c == String.class)的逻辑保证了当前分支返回值类型和T一致,但编译器无法识别这个逻辑关联,只会将返回值视为普通的String/Integer类型,无法和泛型T自动匹配,因此报类型转换错误。
修复方案
方案1:使用Class.cast()做类型转换(推荐)
利用传入的Class<T>实例的cast方法显式转换返回值,编译器会认可该转换的合法性,代码更安全:
public <T> T getValue(MyObject obj, Class<T> c) { if (c == String.class) { return c.cast(obj.getAsString()); } else if (c == Integer.class) { // int基本类型会先自动装箱为Integer再完成转换 return c.cast(obj.getAsInt()); } // 兜底处理不支持的类型,避免逻辑遗漏 throw new IllegalArgumentException("不支持的类型:" + c.getName()); }
方案2:压制unchecked警告
如果确认分支逻辑的类型匹配完全正确,可以添加注解压制编译警告,不过安全性由自己保证:
@SuppressWarnings("unchecked") public <T> T getValue(MyObject obj, Class<T> c) { if (c == String.class) { return (T) obj.getAsString(); } else if (c == Integer.class) { return (T) Integer.valueOf(obj.getAsInt()); } throw new IllegalArgumentException("不支持的类型:" + c.getName()); }
注意事项
- 如果需要支持
int.class(基本类型类对象)入参,需要单独添加if(c == int.class)的分支,因为int.class和Integer.class不是同一个对象,不会匹配现有分支。 - 示例的调用写法
int i = getValue(obj, Integer.class)是合法的,返回的Integer会自动拆箱为int赋值。
内容的提问来源于stack exchange,提问作者Jer
相关产品推荐
相关产品推荐

