开发者

Java Generics and Collections

开发者 https://www.devze.com 2023-01-31 00:27 出处:网络
I have a question about Java Generics and Collections.It\'s considered good practice to declare a collection like this:

I have a question about Java Generics and Collections. It's considered good practice to declare a collection like this:

List<String> catNames = new ArrayList<String>();

because you can change the type of the List and not worry about break开发者_高级运维ing the rest of your code. But when I try to do this:

private static Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, ArrayList<Issue>>();

javac complains

Type mismatch: cannot convert from HashMap<ResultsAggregator.IssueType,ArrayList<Issue>> to HashMap<ResultsAggregator.IssueType,List<Issue>>

Moreover, this is perfectly legal:

private static Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, List<Issue>>();

which seems even more confusing, because List is an interface, not a concrete class. What's going on here? Is this a type erasure issue?


If it was legal to compile such a code, you would've been able to sneakily insert element of other types in the HashMap:

HashMap<IssueType, List<Issue>> a = new HashMap<IssueType, ArrayList<Issue>>();
a.put(someIssue, new SomeClassThatImplementsListOfIssueButIsNotArrayList());

which is not what you expect. ArrayList<String> is a List<String>, but that's not enough for this code to be safe and correct. To be safe, it also requires List<String> to be ArrayList<String>, which means the generic type argument is not covariant here.

Your last code is legal because nothing requires the type parameter to be a concrete class. Similarly, nothing requires a field to be of an abstract type.


There is not reason to specify an ArrayList in your second example. It doesn't actually create a list so it is best to put the interface in there anyway. You will later then able able to call the following just fine.

Map<IssueType, List<Issue>> orphanedAttrMap = new HashMap<IssueType, List<Issue>>();

orphanedAttrMap.put(IssueType.TYPE, new ArrayList<Issue>());
0

精彩评论

暂无评论...
验证码 换一张
取 消