Nathan, It's a tricky one to be sure.
The problem is that the entrySet() method is returning a "Set<Map.Entry<capture-of ? extends K, capture-of ? extends V>>", which is incompatible with the type "Set<Map.Entry<? extends K, ? extends V>>". It's easier to describe why if I drop the "extends K" and "extends V" part. So we have "Set<Map.Entry<?, ?>" and "Set<Map.Entry<capture-of ?, capture-of ?>>". The first one, "Set<Map.Entry<?, ?>>" is a set of Map.Entries of different types - ie it is a heterogeneous collection. It could contain a Map.Entry<Long, Date> and a Map.Entry<String, ResultSet>> and any other pair of types, all in the same set. On the other hand, "Set<Map.Entry<capture-of ?, capture-of ?>>" is a homogenous collection of the same (albeit unknown) pair of types. Eg it might be a Set<Map.Entry<Long, Date>>, so all of the entries in the set MUST be Map.Entry<Long, Date>. In general, even if you could assign this to a local variable without unchecked type safety warnings, you wouldn't be able to call any methods on it because the compiler cannot check whether the access is type-safe. For example you would not be able to call add() because the Set must contain a specific type, but the compiler doesn't know which specific type that is! Regards Neil On 5/11/06, Nathan Beyer <[EMAIL PROTECTED]> wrote:
Does someone understand why this works this way? This seems so odd. I know there are quirks to the generics syntax, but this in an edge I haven't run into yet. I haven't been able to make this one click in my head yet. This compiles fine: public synchronized void putAll(Map<? extends K,? extends V> map) { for (Map.Entry<? extends K,? extends V> entry : map.entrySet()) { ... } } This won't compile at all: public synchronized void putAll(Map<? extends K,? extends V> map) { Set<Map.Entry<? extends K, ? extends V>> entries = map.entrySet(); ... } The error is: Type mismatch: cannot convert from Set<Map.Entry<capture-of ? extends K,capture-of ? extends V>> to Set<Map.Entry<? extends K,? extends V>> The suggested quick fix in Eclipse is "Set<?> entries = ...". This reports a warning: public synchronized void putAll(Map<? extends K,? extends V> map) { Map<K,V> map2 = (Map<K,V>)map; } The warning is: Type safety: The cast from Map<capture-of ? extends K,capture-of ? extends V> to Map<K,V> is actually checking against the erased type Map The suggested quick fix in Eclipse is to the annotation: @SuppressWarnings("unchecked"). -Nathan > -----Original Message----- > From: Tim Ellison [mailto:[EMAIL PROTECTED] > Sent: Wednesday, May 10, 2006 6:59 AM > To: harmony-dev@incubator.apache.org > Subject: Thanks Stepan! (was: Re: [jira] Resolved: (HARMONY-454) > [classlib][luni] java.util.Set generics uplift and related changes) > > Stepan Mishura (JIRA) wrote: > <snip> > > 2) To avoid casting while-loop was replaced with for-loop. Could you > review the change? > > I was scratching my head about this cast, so I was very pleased to see > your elegant solution. > > I must admit that I don't really understand why the for-loop version is > inherently different (other than it 'hides' the casting) -- but I've > learned a new pattern there :-) > > Regards, > Tim > > -- > > Tim Ellison ([EMAIL PROTECTED]) > IBM Java technology centre, UK. > > > --------------------------------------------------------------------- > Terms of use : http://incubator.apache.org/harmony/mailing.html > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- Terms of use : http://incubator.apache.org/harmony/mailing.html To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
-- Neil Bartlett Senior Technical Consultant, Integility Ltd Tel: +44 (0) 20 7043 8328 Fax: +44 (0) 20 7043 8329 LinkedIn Profile: https://www.linkedin.com/in/neilbartlett