Reputation: 1006
Java tutorial says that <?>
and <T>
are interchangeable. Why then can I compile line 1 below, while I cannot compile line [2]?
abstract class A<K extends Number>{
abstract public A<?> f(A<?> k); //[1]
abstract public <S> A<S> f(A<S> k); //[2]
}
Upvotes: 2
Views: 166
Reputation: 1006
After many hours of reading and searching, I have eventually found the answer to my own question.
First of all, I have to say about <?>
, there is some information here.
So what is the supertype of all kinds of collections? It's written Collection
<?>
(pronounced "collection of unknown"), that is, a collection whose element type matches anything.(Java tutorials)
Ok, so our A<?>
is super type of all kinds of As.
And parametr A<?>
can accept any of As (polymorphically) as a argument therefore line 1 compiles.
Java specification tells us:
Wildcards are a restricted form of existential types. Given a generic type declaration
G<T extends B>
,G<?>
is roughly analogous to SomeX<:B
.G<X>
B stands for bounds; X<:B
indicates that the subtype relation holds between
types X and B.
Therefore A<?>
is indeed auto-restricted;
When we declare type argument <S>
, it is, in some way, as if we declared class S{}
, type S don't have any relations to Number(our bound) and cast to one would fail, so we should declare that "S extends Number" to have the same effect as for <?>
.
Upvotes: 1
Reputation: 31724
?
and T
are interchangeable (not truly, as you are loosing the exact type) given there are no bounds.
In this case, K
has a bound that it extends Number
Hence making it to abstract public <S extends Number> A<S> f(A<S> k);
will do
Upvotes: 0
Reputation: 15560
You have to restrict S
to extend Number
:
abstract class A<K extends Number>{
//abstract public A<?> f(A<?> k); //[1]
abstract public <S extends Number> A<S> f(A<S> k); //[2]
}
I guess when you use <?>
it's auto-restricted - really don't know.
Upvotes: 3
Reputation: 2857
this compiles fine for me:
abstract class A<K extends Number>
{
// abstract public A<?> f(A<?> k); //[1]
abstract public A<K> f(A<K> k);
}
Upvotes: 0