Community
Participate
Working Groups
Build ID: I20071016-1215 Try to compile this code... Set<List> listSet = new HashSet<List>(); Set<List> otherListSet = new HashSet<List>(); otherListSet.add((List) listSet); Set<String> stringSet = new HashSet<String>(); Set<String> otherStringSet = new HashSet<String>(); otherStringSet.add((String) stringSet); The first block of code compiles fine but gives a runtime error, stating that Set<String> cannot be cast to String. The second does not compile, giving the same error at compile time. Now what I don't understand: Why, in the case of a concrete type parameter (String) is the error reported statically but not in the case of an interface type parameter? What I even understand less: javac seems to expose the same strange behavior... How can this not be a bug?
The difference comes from the fact that String is a final class, so statically the compiler can tell no better subtype may show up at runtime, hence the cast is refused at compile time. For the first case, with interface, you could imagine the runtime object to be a subtype of Set which implements List, hence the cast would be legite. In your example, we can easily spot that HashSet doesn't implement List, hence it could statically be doomed, but the compiler is not checking based on assigned values, only using declaring types. So, by the spec, our behavior is fine. Added GenericTypeTest#test1221 Closing as INVALID.
Thanks, Philippe, for the explanation. However I still have one question: (In reply to comment #1) > In your example, we can easily spot that HashSet doesn't implement List, hence > it could statically be doomed, but the compiler is not checking based on > assigned values, only using declaring types. Even in that case the cast should be invalid. The declared type is Set<List>, which certainly is not a subtype of List. So how can this cast succeed?
What if later at runtime the actual value to cast is of type X, where X implements both Set<List> and List ?
(In reply to comment #3) > What if later at runtime the actual value to cast is of type X, where X > implements both Set<List> and List ? > Ahh, now I got it. Thanks a lot for the clarification!
Verified for 3.4M4 using build I20071210-1800.