我可以声明使用泛型指定地图类型映射的数组:
private Map<String, Integer>[] myMaps;
但是,我想不出如何正确实例吧:
myMaps = new HashMap<String, Integer>[count]; // gives "generic array creation" error
myMaps = new HashMap[count]; // gives an "unchecked or unsafe operation" warning
myMaps = (Map<String, Integer>[])new HashMap[count]; // also gives warning
我怎样才能实例化没有得到一个编译器错误或警告该阵列的地图?
更新:
谢谢大家的回复。 我结束了名单的建议下去。
没有严格的回答你的问题,但你有没有考虑过使用一个List
呢?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
似乎工作就好了。
见Java理论与实践:泛型陷阱对于为什么使用泛型混合阵列气馁的详细说明。
更新:
正如在评论中提到的德鲁,它可能是更好的使用采集接口,而不是List
。 这可能会派上用场,如果你需要更改的Set
,或其他子接口的一个Collection
。 示例代码:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());
以此为起点,你只需要改变HashSet
到ArrayList
, PriorityQueue
,或实现任何其他的类Collection
。
你不能安全地创建一个通用的阵列。 有效的Java第二版进入在细节上泛型章节 。 开始在119页的最后一段:
为什么非法创建一个通用的阵列? 因为它不是类型安全的。 如果它是合法的,在原本正确的程序可能会在运行时失败了由编译器生成蒙上ClassCastException
。 这将违反由通用类型系统提供了根本保证。
为了使这更具体,考虑下面的代码片段:
// Why generic array creation is illegal - won't compile! List<String>[] stringLists = new List<String>[1]; // (1) List<Integer> intList = Arrays.asList(42); // (2) Object[] objects = stringLists; // (3) objects[0] = intList; // (4) String s = stringLists[0].get(0); // (5)
让我们假设1号线,这将创建一个通用的阵列,是合法的。 2线创建并初始化一个List<Integer>
含有单个元件。 线3个存储List<String>
阵列成Object
数组变量,因为阵列是协变,其是合法的。 线4个存储List<Integer>
成的鞋底元件Object
阵列,其成功,因为泛型是通过擦除实现:运行时类型的List<Integer>
实例是简单地List
,和一个的运行时类型List<String>[]
实例List[]
所以这个任务不产生ArrayStoreException
。 现在,我们就麻烦了。 我们已经存储在List<Integer>
实例到该声明仅容纳一个数组List<String>
实例。 在第5行,我们检索该数组中的唯一列表中的唯一元素。 编译器自动转换检索元素String
,但它是一个Integer
,所以我们得到一个ClassCastException
运行时。 为了防止这种情况的发生,线1(其创建一个通用阵列)产生编译时间错误。
因为数组和泛型没有很好地结合起来(以及其他原因),它通常最好使用Collection
的对象(尤其是List
对象),而不是阵列。
一般来说它不是在Java中,混合泛型和数组更好的使用ArrayList是一个好主意。
如果你必须使用一个数组,来处理这一点的最好办法是把数组创建(你的例子2或3)在一个单独的方法,并用@SuppressWarnings注释它(“未登记”)。
简短的回答似乎是,你真的不能。
看到一个关于它的博客以下。 http://www.bloggingaboutjava.org/2006/01/java-generics-quirks/
其中一个评论的博客指出:
事实上,工程师们做了这样一个数组非法的创建。 因此,从通用类数组的创建失败。 该Collection.toArray方法后跟一个演员到阵列工作在编译时。
这解决不是问题,该ArrayStoreCheck不能在运行过程中完成的,但你可以通过这种方式创建泛型数组。
正如比尔的蜥蜴建议,你可能有过使用更好的
List<Map<String,Integer>>
myMaps = new HashMap<String, Integer>[10]();
所以,这是错误的
为什么不把地图列表,而不是试图让一个数组?
List<Map<String, Integer>> mymaps = new ArrayList<Map<String, Integer>>(count);