Java自定义HashMap泛型转Integer报错的原因与解决方法问询
问题原因
- 泛型类型擦除机制:Java泛型是编译期特性,编译后泛型参数
T会被擦除为Object(未指定上界时)。编译器在编译阶段无法确认T的实际类型就是Integer,即便你通过instanceof做了运行时类型判断,编译期的类型检查依然会阻止直接将Integer(或int)强转为T。 - 基本类型与引用类型的差异:
temp + (Integer)value的计算结果是int基本类型,而T是引用类型参数,Java不允许直接将基本类型强转为泛型引用类型,必须先装箱为对应的包装类(Integer)后再尝试转换。
可行解决办法
方法1:先装箱为Integer再强转T(消除编译警告)
既然已经通过instanceof确认当前T的实际类型是Integer,可以先将相加结果装箱为Integer,再强转为T。编译期会产生unchecked警告,但运行时是安全的,可通过注解消除警告:
@SuppressWarnings("unchecked") public void put(String key, T value){ int i = searchKey(key); if(i != -1 && value instanceof Integer && hTable[i].getValue() instanceof Integer){ Integer temp = (Integer)hTable[i].getValue(); Integer sum = temp + (Integer) value; // 先转Integer再转T,运行时安全 hTable[i].setValue((T) sum); } // 其他无关逻辑 }
方法2:通过Object中间变量绕过编译检查
如果不想添加注解,也可以用Object作为过渡类型,因为Object可以强转为任意引用类型:
public void put(String key, T value){ int i = searchKey(key); if(i != -1 && value instanceof Integer && hTable[i].getValue() instanceof Integer){ Integer temp = (Integer)hTable[i].getValue(); Object sum = temp + (Integer) value; hTable[i].setValue((T) sum); } // 其他无关逻辑 }
这种方式同样会产生unchecked警告,本质和方法1一致,只是多了一层Object过渡。
补充说明
如果你的HashMap不需要支持非数值类型的value,可以将泛型上界设为Number(class HashTable<T extends Number>),但根据你的需求要保留泛型通用性,上面的方法更适配场景。
内容的提问来源于stack exchange,提问作者Je-Yu Chou
相关产品推荐
相关产品推荐

