如何解决未检查类型转换问题?在ArrayList<T>中实现T且不抑制警告
解决泛型未检查类型转换问题的方案
嘿,我来帮你搞定这个泛型类型转换的麻烦事儿~你遇到的警告本质是因为Java的泛型类型擦除:编译后T的实际类型信息会丢失,所以(T[])(new Object[RANDOM_NUMBER])这种强制转换,JVM在运行时没法验证它的安全性,才会弹出未检查转换的警告。下面给你两种不用抑制警告的解决思路:
方案一:用ArrayList替代数组存储顶点(推荐)
直接把存储顶点的数组换成ArrayList,完全绕开数组的类型转换问题,代码更简洁也更符合Java集合的使用习惯:
public class AdjMatrix <T extends Object> implements Blah<T> { // 把数组换成ArrayList<T> public ArrayList<T> vertex; public AdjMatrix() { // 直接初始化泛型集合,无类型转换问题 this.vertex = new ArrayList<>(RANDOM_NUMBER); } public ArrayList<T> neighbours(T vertLabel) { ArrayList<T> neighbours = new ArrayList<T>(); // 后续正常编写邻居查找逻辑即可,泛型会在编译时帮你做类型检查 // ... return neighbours; } }
方案二:通过反射创建正确类型的数组(如果必须用数组)
如果你一定要用数组存储,可以通过反射在运行时获取T的类型信息,创建真正的T类型数组,这样就不会有未检查转换的警告:
import java.lang.reflect.Array; public class AdjMatrix <T extends Object> implements Blah<T> { public T[] vertex; // 构造函数需要传入T的Class对象,用来创建正确类型的数组 public AdjMatrix(Class<T> clazz) { // 用反射创建指定类型和长度的数组 this.vertex = (T[]) Array.newInstance(clazz, RANDOM_NUMBER); } public ArrayList<T> neighbours(T vertLabel) { ArrayList<T> neighbours = new ArrayList<T>(); // 这里操作vertex数组时,类型是安全的,因为它是真正的T[] // ... return neighbours; } }
使用这个方案时,创建AdjMatrix实例需要传入T的Class,比如AdjMatrix<String> matrix = new AdjMatrix<>(String.class);
不管用哪种方案,你的neighbours方法里往ArrayList<T>添加元素的逻辑都会是类型安全的,编译时就能检查出类型错误,不用再担心未检查转换的问题啦~
内容的提问来源于stack exchange,提问作者Tim Davis




