Ismael Juma wrote:
Sebastiaan van Erk <[EMAIL PROTECTED]> writes:
He also discusses the difference between bounded wildcards and bounded type parameters (one of the problems already encountered).

Yes, but he doesn't explain the issue that has left people confused. Bloch says:

"These two signatures have identical semantics
 - boolean addAll(Collection<? extends E> c);
 - <T extends E> boolean addAll(Collection<T> c);"

Once you add a type parameter to E, it either doesn't apply anymore or the
compilers are buggy. More specifically, these two are not the same according to
the eclipse compiler and javac:

- public final <C extends Page<?>> void setResponsePage(final Class<C> cls,
PageParameters parameters)
- public final void setResponsePage(final Class<? extends Page<?>> cls,
PageParameters parameters)

The former accepts some class literals that the latter does not.

If two compilers disagree, this would seem to be a bug in at least one of them! :-)

However, I couldn't stand not knowing why the above stuff wasn't working, and I *FINALLY* figured it out and it comes down to this:

In a nutshell:
        Foo<Bar<T>> is ****NOT**** a subtype of Foo<Bar<?>>
just like
        List<String> is ****NOT**** a subtype of List<Object>

When A is a subtype of B, you can make the assignment B b = (A) a. It is obvious why you cannot do:

        ArrayList<Object> list = new ArrayList<String>();

This is not typesafe, you can do list.add(new Object()) and pollute a String list with Objects.

Similarly you cannot do:

        ArrayList<List<?>> list = new ArrayList<List<String>>(); // bad!!!

Why is that? Because the list instance now has the add(List<?> el) method!!!!

        list.add(new ArrayList<Object>()); // allowed!!!!

Thus you could pollute the List of (List of String) by adding (List of Object)!!

When you use a type bound, you do not have this problem:

1) public Object method(Foo<? extends Bar<?>> y)

You cannot call method((Foo<SubBar<T>>) y) because SubBar<T> is not a subtype of ? extends Bar<?> for the above reasons.

2) public <S extends Bar<?>> Object method(Foo<S> y)

The type parameter is bounded, and now it is allowed to use SubBar<T> because the T is captured by the wildcard and the method has signature method(Foo<SubBar<T>> y) and thus takes a type *without* wildcards.

So, it is after all, not a compiler error, and not semantically equivalent. Pretty mind-bending stuff though. :-) Who said generics are easy? ;-)

Regards,
Sebastiaan




Regards,
Ismael




Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to