[英]Java Generics and Collections
我有一个关于Java Generics和Collections的问题。 声明像这样的集合被认为是一种好习惯:
List<String> catNames = new ArrayList<String>();
因为您可以更改List
的类型,而不必担心会破坏其余的代码。 但是当我尝试这样做时:
private static Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, ArrayList<Issue>>();
javac
抱怨
Type mismatch: cannot convert from HashMap<ResultsAggregator.IssueType,ArrayList<Issue>> to HashMap<ResultsAggregator.IssueType,List<Issue>>
而且,这是完全合法的:
private static Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, List<Issue>>();
这似乎更令人困惑,因为List
是一个接口,而不是具体的类。 这里发生了什么? 这是一种类型擦除问题吗?
如果编译这样的代码是合法的,你就可以偷偷地在HashMap
插入其他类型的元素:
HashMap<IssueType, List<Issue>> a = new HashMap<IssueType, ArrayList<Issue>>();
a.put(someIssue, new SomeClassThatImplementsListOfIssueButIsNotArrayList());
这不是你所期望的。 ArrayList<String>
是一个List<String>
,但这还不足以使此代码安全无误。 为了安全起见,它还要求List<String>
为ArrayList<String>
,这意味着泛型类型参数在此处不是协变的。
您的上一个代码是合法的,因为没有必要将type参数作为具体类。 同样,没有什么要求字段是抽象类型。
在第二个示例中没有理由指定ArrayList。 它实际上并不创建列表,因此最好将接口放在那里。 您稍后可以调用以下内容。
Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, List<Issue>>();
orphanedAttrMap.put(IssueType.TYPE, new ArrayList<Issue>());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.