0

Declaration like this :

  class A<X extends Number & List> {  } 

is allowed.Whereas declaration like this is not allowed.

  class A<? extends Number & List> {  }

Is there any logical explanation about why Java restricts us to do that?

& what's the actual difference between

      <T extends Number>  
     & <? extends Number>?
Debadyuti Maiti
  • 1,099
  • 4
  • 18
  • 30
  • 1
    Do you actually have a class that extends `Number` and implements `List`? Or does it extend `Number` and implement `List`? or does X extend `Number` and implement `List`? How would you even write that last one without declaring the type `X` somewhere? – Paul Hanbury Mar 28 '12 at 19:37
  • Good point -- `Number` and `List` aren't really types you'd expect to coexist like that. – Louis Wasserman Mar 28 '12 at 19:39
  • @LouisWasserman: Even if they do coexist like that, I was just pointing out that you might need the generic definition to specify what your list is holding. Either way, it is probably better to avoid the raw type. – Paul Hanbury Mar 28 '12 at 19:48
  • @PaulHanbury: They are tested & compiled successfully.Number & List are taken just for example.You can replace them with any custom class name,interface name.The point here is why wild card is not allowed in generic class/method declaration. – Debadyuti Maiti Mar 29 '12 at 13:20
  • @DebadyutiMaiti: By your logic, I should be happy with the following code because it compiles and passes its tests: `public class Math {public static int multiply(int x,int y){int p = 0;for(int i=0;i – Paul Hanbury Apr 19 '12 at 15:03
  • @DebadyutiMaiti: My point, however was that you need to explicitly name your type (i.e., "X", not "?") so that you can refer to it within the rest of your code. – Paul Hanbury Apr 19 '12 at 15:03

3 Answers3

3

If you used <? extends Number & List>, then you wouldn't be able to do anything with the type parameter. It'd be completely useless.

Similarly, ? extends Number lets you deal with the special case when you don't need to refer to the type that extends number, and you don't need to give it a name.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
2

The whole point of a type parameter like T is so that you can use it as a type inside the class. What would a wildcard there even mean? If you can't use it anywhere, why have a type parameter at all?

newacct
  • 119,665
  • 29
  • 163
  • 224
0

Generic class and interface declarations want type parameters, such as T or U. ? is a wildcard, better used for method parameters that are themselves generic:

class Foo<T extends Number & List> {
    void doStuff(List<T> items) {
        // ...
    }

    void doMoreStuff(List<? extends OutputStream> streams) {
        // ...
    }
}

doStuff() indicates that it wants to operate on a List<T> where T is the type parameter on class Foo. So:

class Weird extends Number implements List {
    //
}

Foo<Weird> f = new Foo<Weird>();
f.doStuff(...);   // wants a List<Weird>

If we called doMoreStuff() on f, we could hand it something of type List<OutputStream>, List<FilterOutputStream>, List<ByteArrayOutputStream>, etc.

pholser
  • 4,908
  • 1
  • 27
  • 37