我可以使用泛型来声明一个映射数组,以指定映射类型:
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如何在不收到编译器错误或警告的情况下实例化此映射数组?
更新:
谢谢大家的答复。最后我接受了清单上的建议。
发布于 2009-09-29 15:22:19
您不能安全地创建一个泛型数组。有效的Java2Edition将在关于概论的章节中详细介绍。从第119页最后一段开始:
为什么创建泛型数组是非法的?因为它不是打字机。如果它是合法的,编译器在其他正确的程序中生成的转换可能会在运行时与
ClassCastException一起失败。这将违反通用类型系统提供的基本保证。 为了使这更具体,请考虑以下代码片段: //为什么泛型数组的创建是非法的-不会编译!List[] stringLists =新List1;// (1) List intList = Arrays.asList(42);/ (2) Object[] objects = stringLists;// (3) objects = intList;/ (4) String s= stringLists.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对象)而不是数组。
发布于 2009-09-29 15:17:56
不是严格地回答您的问题,但是您考虑过使用List来代替吗?
List<Map<String,Integer>> maps = new ArrayList<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());似乎运作得很好。
有关为什么不鼓励将数组与泛型混合的详细说明,请参见Java理论与实践:泛型问题。
更新:
正如Drew在注释中提到的那样,使用集合接口而不是List可能更好。如果您需要更改为Set或Collection的其他子接口之一,这可能会派上用场。示例代码:
Collection<Map<String,Integer>> maps = new HashSet<Map<String,Integer>>();
...
maps.add(new HashMap<String,Integer>());从这个起点开始,您只需要将HashSet更改为ArrayList、PriorityQueue或实现Collection的任何其他类。
发布于 2009-09-29 15:11:23
通常,在Java中混合泛型和数组并不是一个好主意,最好使用ArrayList。
如果必须使用数组,处理这一问题的最佳方法是将数组创建(示例2或3)放在单独的方法中,并使用@SuppressWarnings("unchecked")对其进行注释。
https://stackoverflow.com/questions/1493162
复制相似问题