1

So why can we able to instantiate Pair but we can't able to instantiate Pair

Pair<T> p=new Pair<T>();

VS

Pair<?> p=new Pair<?>();

I know that <?> mean unknown type --> <? extends Object>

but isn't <T> mean the same thing ---> <T extends Object>

Anyone have an idea?

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
skystar7
  • 4,419
  • 11
  • 38
  • 41

3 Answers3

3

<T> on its own doesn't mean anything. The T type must be defined somewhere, either on your class or method level, e.g.:

public class PairFactory<T> {
  public Pair<T> makePair() {
    return new Pair<T>();
  }
}

In this case you decide on <T> during instantiation:

new PairFactory<String>();

This is a bit more involved:

public <T> Pair<T> makePair() {
  return new Pair<T>();
}

The compiler will try to figure out the type based on context, e.g.:

Pair<Date> p = makePair();
Harmlezz
  • 7,972
  • 27
  • 35
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • @skystar7: that's what I'm trying to explain (sorry if it's not clear): `new Pair` works because `T` is defined somewhere earlier. `>` is just a placeholder and `new Pair>` is never fully defined – Tomasz Nurkiewicz Dec 20 '12 at 21:53
  • 1
    Thank you...i got what you mean now – skystar7 Dec 20 '12 at 21:56
  • How could the compiler allocate memory for an Object if it doesn't know what type it is?? – jahroy Dec 20 '12 at 21:57
  • @jahroy: first of all, it knows, `T` is known at compile time. Secondly it doesn't have to know, these objects barely hold *references* to type `T`. References are simply 32- or 64-bit pointers. It's up to you to create said objects later. – Tomasz Nurkiewicz Dec 20 '12 at 21:58
  • I was referring to when `>` is used in stead of `` (but my comment was probably still way off)... – jahroy Dec 20 '12 at 22:14
2

No, ? and T are not the same thing. ? represents a wildcard generic type parameter -- it could be anything at runtime. T represents a generic type parameter that will be a specific type at runtime -- we just don't know it at compile-time.

That is, a List<?> could contain Strings, Integers, Floats, etc. A List<T> can only contain whatever T is parameterized as.

Thorn G
  • 12,620
  • 2
  • 44
  • 56
0

You are not allowed to instantiate with a wildcard as parameter, because it is generally useless. Instead, you can just use any reference type that is within the bounds of the type parameter (in this case, there are no bounds, so just any reference type):

class SuperCrazyBogusType { }
Pair<?> p = new Pair<SuperCrazyBogusType>();

(or you can use a more normal type like Object).

Do you see how weird that is? Yes, you can instantiate using any arbitrary type out there, even ones that have no relation to the rest of your program or what you are doing. And yes, it is 100% safe and correct, because all you wanted was a Pair<?> (a pair of some unknown type).

That points out why it is ridiculous, and why the syntax for doing this is unnecessary. There is almost nothing you can do with the Pair<?> you get (e.g. you cannot put any data into it), because you don't know the type parameter.

newacct
  • 119,665
  • 29
  • 163
  • 224