Eddie Jamsession
Eddie Jamsession

Reputation: 1006

Are <?> and <E> interchangeable?

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

Answers (4)

Eddie Jamsession
Eddie Jamsession

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 tutorials

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 Some X<: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

Jatin
Jatin

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

mgarciaisaia
mgarciaisaia

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

kellogs
kellogs

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

Related Questions