You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Stepan Mishura <st...@gmail.com> on 2006/06/01 04:33:16 UTC

Re: [classlib] generics puzzler

On 6/1/06, Nathan Beyer wrote:
>
> For anyone interested, I finally figured out the answer to this puzzle.
>
> The following code compiles without error or warning using the new foreach
> loop.
>
> for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
>        entry.toString();
> }
>
> The way to make this work without a compile error or warning and use an
> Iterator, you have to declare the Iterator just right.
>
> Iterator<? extends Map.Entry<? extends K, ? extends V>> it =
> t.entrySet().iterator();
> while(it.hasNext()) {
>        Map.Entry<? extends K, ? extends V> entry = it.next();
> }
>
> The key is the "? extends" before the Map.Entry declaration.


Cool! Thanks!!!

-Stepan.

-Nathan
>
> > -----Original Message-----
> > From: Tim Ellison [mailto:t.p.ellison@gmail.com]
> > Sent: Thursday, May 11, 2006 3:30 AM
> > To: harmony-dev@incubator.apache.org
> > Subject: [classlib] generics puzzler (was: Re: Thanks Stepan! (was: Re:
> > [jira] Resolved: (HARMONY-454) [classlib][luni] java.util.Set generics
> > uplift and related changes))
> >
> > But the question remains in my mind whether there is any generic type
> > definition you could write that would allow you to cast the  entrySet()
> > to a "Set<Map.Entry<capture-of ? extends K, capture-of ? extends V>>"
> > equivalent?
> >
> > To put it another way, I would expect that
> >       for (Map.Entry<? extends K, ? extends V> entry : map.entrySet())
> >
> > should complain that the declaration of 'entry' is not compatible with
> > the 'capture-of ? extends K' etc.
> >
> > (It's still a useful cheat though)
> >
> > Regards,
> > Tim
> >
> >
> > Neil Bartlett wrote:
> > > 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 <nb...@kc.rr.com> 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:t.p.ellison@gmail.com]
> > >> > 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 (t.p.ellison@gmail.com)
> > >> > IBM Java technology centre, UK.
> > >> >
> > >> >
>
>

-- 
Thanks,
Stepan Mishura
Intel Middleware Products Division

------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: harmony-dev-unsubscribe@incubator.apache.org
For additional commands, e-mail: harmony-dev-help@incubator.apache.org