| Author |
Confusion with Wildcards from generics
|
Dany Mariana
Greenhorn
Joined: Oct 31, 2009
Posts: 12
|
|
Hello everyone,
I did the lab for SCJP 6 and I didn't understand something regarding wildcards to generics.
Could you please explain to me why this works:
abstract class A<K extends Number>
{
//insert code independently here
public abstract <K> A<? extends Number> useMe(A<? super Number>k)
Why A<K extends Number> accept A<? super Number> ?
In my mind A<K extends Number> this means: A<Number>, A<Integer>, A<Short> etc but A<? super Number> means A<Object> and A<Number> so this are different.
I was spending all my yesterday evening and today reading about wildcards. I think I am missing something but I don't know what. Please help me
|
 |
Henry Wong
author
Sheriff
Joined: Sep 28, 2004
Posts: 16687
|
|
Dany Cleo wrote:
Why A<K extends Number> accept A<? super Number> ?
In my mind A<K extends Number> this means: A<Number>, A<Integer>, A<Short> etc but A<? super Number> means A<Object> and A<Number> so this are different.
I was spending all my yesterday evening and today reading about wildcards. I think I am missing something but I don't know what. Please help me
A<? super Number> is actually a silly declaration, but it is legal. Why is it silly?
Basically, an A<? super Number> reference could refer to an A<Object> or A<Number> instance, but as you already mentioned, A<Object> is not legal -- so... A<? super Number> can only be pointed to an A<Number> object.... you have a method that can only be passed A<Number> instance, but is written to treat it as an unknown bounded type.
Henry
|
Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
|
 |
Dany Mariana
Greenhorn
Joined: Oct 31, 2009
Posts: 12
|
|
This is legal because Number extends only Object class?
Henry Wong wrote:
Dany Cleo wrote:
Why A<K extends Number> accept A<? super Number> ?
In my mind A<K extends Number> this means: A<Number>, A<Integer>, A<Short> etc but A<? super Number> means A<Object> and A<Number> so this are different.
I was spending all my yesterday evening and today reading about wildcards. I think I am missing something but I don't know what. Please help me
A<? super Number> is actually a silly declaration, but it is legal. Why is it silly?
Basically, an A<? super Number> reference could refer to an A<Object> or A<Number> instance, but as you already mentioned, A<Object> is not legal -- so... A<? super Number> can only be pointed to an A<Number> object.... you have a method that can only be passed A<Number> instance, but is written to treat it as an unknown bounded type.
Henry
|
 |
zhong chen
Greenhorn
Joined: Oct 12, 2009
Posts: 24
|
|
I have the same doubt. What's the contract for the type parameter in the class declaration A<K extends Number>?
Actually you can do the following and the code still compiles:
public abstract A<?> useMe(A<?>k);
No limitation inside the brackets after A, why?
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
This is legal because Number extends only Object class?
What Henry is trying to say here is that the type declaration in A<? super Number> k can only accept A<Number> nothing else. So the declaration is kinda unusual but legal. If you see the declaration A<? super Number> it can accept A<Number> or A<Object> or A<Serializable> (Number implements Serializable). But since the class A allows only types which are subtypes of Number or Number itself, so thus the declaration A<? super Number> cannot accept A<Object> or A<Serializable>, thus the only allowed type to be passed to the method is A<Number>.
Actually you can do the following and the code still compiles:
public abstract A<?> useMe(A<?>k);
Again, the only type allowed to be passed to the method here will be decided by the class declaration i.e. A<K extends Number>. So you cannot pass anything to this method. You actually will have to pass A<? extends Number> i.e. A should be of type Number or a subclass of Number. So again the declaration is allowed, but its silly...
|
SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
|
 |
Henry Wong
author
Sheriff
Joined: Sep 28, 2004
Posts: 16687
|
|
Ankit Garg wrote:
Actually you can do the following and the code still compiles:
public abstract A<?> useMe(A<?>k);
Again, the only type allowed to be passed to the method here will be decided by the class declaration i.e. A<K extends Number>. So you cannot pass anything to this method. You actually will have to pass A<? extends Number> i.e. A should be of type Number or a subclass of Number. So again the declaration is allowed, but its silly...
Actually, in this case, the parameter can be passed A<Integer>, A<Float>, A<Double>, etc. etc. etc., the paramater wildcard is not bounded.
zhong chen wrote:
No limitation inside the brackets after A, why?
Just because the method is treating (coded for) the type as having no limitation (unbounded), doesn't mean that you can actually instantiate all possible type. It is just that this method can be coded as such (for all types), and hence, can be used for all legal types. As long as the method can be applied a possible legal type, the compiler won't complain.
Henry
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
Henry Wong wrote:Actually, in this case, the parameter can be passed A<Integer>, A<Float>, A<Double>, etc. etc. etc., the paramater wildcard is not bounded.
Yes that's what I meant too, maybe my language was wrong . The method allows any type of A to be passed to it, but since the class A itself can only be of type <K extends Number> so actually the method can be called only by using A<Integer>, A<Float>, A<Double>, etc. etc. etc.
|
 |
zhong chen
Greenhorn
Joined: Oct 12, 2009
Posts: 24
|
|
As long as the method can be applied a possible legal type, the compiler won't complain.
That's true. But I couldn't find this statement in Java documentation. Could you tell us where can we find the Generics docs?
|
 |
Dany Mariana
Greenhorn
Joined: Oct 31, 2009
Posts: 12
|
|
Thank you a lot for you explications.
Now is more clear and it wouldn't be without your explications.
Thank you a lot
Henry Wong wrote:
Ankit Garg wrote:
Actually you can do the following and the code still compiles:
public abstract A<?> useMe(A<?>k);
Again, the only type allowed to be passed to the method here will be decided by the class declaration i.e. A<K extends Number>. So you cannot pass anything to this method. You actually will have to pass A<? extends Number> i.e. A should be of type Number or a subclass of Number. So again the declaration is allowed, but its silly...
Actually, in this case, the parameter can be passed A<Integer>, A<Float>, A<Double>, etc. etc. etc., the paramater wildcard is not bounded.
zhong chen wrote:
No limitation inside the brackets after A, why?
Just because the method is treating (coded for) the type as having no limitation (unbounded), doesn't mean that you can actually instantiate all possible type. It is just that this method can be coded as such (for all types), and hence, can be used for all legal types. As long as the method can be applied a possible legal type, the compiler won't complain.
Henry
|
 |
Henry Wong
author
Sheriff
Joined: Sep 28, 2004
Posts: 16687
|
|
zhong chen wrote:That's true. But I couldn't find this statement in Java documentation. Could you tell us where can we find the Generics docs?
Interesting. I never thought to confirm this via the specification. This was one of those "so the compiler is complaining, why, okay that makes sense, don't do that" kind of thing. If someone wants to go through the trouble, please post a link here -- I would like to see its definition too.
Henry
|
 |
Ankit Garg
Saloon Keeper
Joined: Aug 03, 2008
Posts: 9189
|
|
Some resources on generics
Generics FAQ by Angelika Langer
Sun Generics Tutorial (PDF)
Generics Tutorial from Sun
Also you can look into different generics sections in the JLS...
|
 |
 |
|
|
subject: Confusion with Wildcards from generics
|
|
|