如何创建Map.Entry<Integer, Integer>类型数组?Java报错求助
首先咱们先理清第一个核心问题:为什么直接创建Map.Entry<Integer, Integer>[]会报错?
Java的泛型是基于类型擦除实现的——编译后所有泛型类型信息都会被擦除成原始类型(比如Map.Entry<Integer, Integer>会变成Map.Entry)。而数组在创建时需要明确知道具体的运行时类型,泛型类型因为擦除无法提供这个信息,所以编译器直接禁止了这种写法,这就是你看到Cannot create a generic array of Map.Entry错误的原因。
再看你自定义的createTarray类,问题出在实例化时传递的Class参数上:Map.Entry<Integer,Integer>.class是非法写法。因为泛型参数在运行时根本不存在,你没法获取带泛型参数的Class对象,正确的写法应该是传递Map.Entry.class。
修正后的代码示例
你的createTarray类可以保留,只需要修改实例化的方式:
import java.lang.reflect.Array; import java.util.Map; class CreateTarray<T> { private T[] ts; @SuppressWarnings("unchecked") public CreateTarray(Class<?> clazz, int length) { ts = (T[]) Array.newInstance(clazz, length); } public T[] getTarray() { return ts; } } public class Main { public static void main(String[] args) { int number = 10; // 重点:传递不带泛型参数的Map.Entry.class CreateTarray<Map.Entry<Integer, Integer>> tarray = new CreateTarray<>(Map.Entry.class, number); Map.Entry<Integer, Integer>[] entrys = tarray.getTarray(); // 现在可以正常使用数组了,比如赋值 entrys[0] = Map.entry(1, 2); System.out.println(entrys[0]); } }
为什么这样能行?
Array.newInstance(clazz, length)会创建一个原始类型的数组(这里是Map.Entry[]),然后我们通过强制类型转换为T[](也就是Map.Entry<Integer, Integer>[])。虽然会触发unchecked警告,但我们通过@SuppressWarnings("unchecked")抑制它——因为我们明确后续只会往数组里放Map.Entry<Integer, Integer>类型的元素,这个转换是安全的。
更推荐的替代方案:用List代替数组
其实在Java里,泛型数组的使用场景非常有限,更推荐用List<Map.Entry<Integer, Integer>>来替代数组,这样能完全避开泛型数组的类型安全问题,写法也更简洁:
import java.util.ArrayList; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { int number = 10; List<Map.Entry<Integer, Integer>> entryList = new ArrayList<>(number); // 添加元素 entryList.add(Map.entry(1, 2)); entryList.add(Map.entry(3, 4)); // 访问元素 System.out.println(entryList.get(0)); } }
List对泛型的支持比数组友好得多,不需要处理反射和类型转换的麻烦,代码的可读性和安全性都更高。
内容的提问来源于stack exchange,提问作者wuhui

