11

In Generics

class A<T extends Number> is allowed

But

class A<T super Integer> is not allowed

I'm not getting this point. This may sound like novice question but I'm stuck in it

Paolo Forgia
  • 5,804
  • 7
  • 39
  • 55
emotionlessbananas
  • 1,095
  • 2
  • 17
  • 34
  • This will clarify :- http://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java – Apollo May 24 '16 at 10:49
  • @akhil wildcard `?` is not allowed at class level – emotionlessbananas May 24 '16 at 10:51
  • "Correct me if I'm wrong": [*Producer Extends; Consumer Super*](http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super). So `super` is used when you are putting data into a structure; `extends` is used when you are taking it out. – Andy Turner May 24 '16 at 10:51
  • The wildcard ? in Java is a special actual parameter for the instantiation of generic (parameterized) types. It can be used for the instantiation, not in the definition of a generic unit. – Apollo May 24 '16 at 10:55
  • 3
    This is explicitly answered in the FAQ by Angelika Langer: [Why is there no lower bound for type parameters?](http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Why%20is%20there%20no%20lower%20bound%20for%20type%20parameters?). (Long story short: It does not make sense...) – Marco13 May 24 '16 at 10:58
  • @AndyTurner sounds confusing given:`Collections#addAll(Collection extends E> c)` (although not wrong, the structure you mean here is `c`, not the collection added to) – zapl May 24 '16 at 10:58

2 Answers2

8

Quoting Java Generics: extends, super and wildcards explained:

The super bound is not allowed in class definition.

//this code does not compile !
class Forbidden<X super Vehicle> { }

Why? Because such construction doesn't make sense. For example, you can't erase the type parameter with Vehicle because the class Forbidden could be instantiated with Object. So you have to erase type parameters to Object anyway. If think about class Forbidden, it can take any value in place of X, not only superclasses of Vehicle. There's no point in using super bound, it wouldn't get us anything. Thus it is not allowed.

Community
  • 1
  • 1
Andy Turner
  • 122,430
  • 10
  • 138
  • 216
  • 7
    I know I am late to comment on this. Please clear this query of mine: "you can't erase the type parameter with Vehicle because the class Forbidden could be instantiated with Object" Isn't this true in case of "List super Number>" ? This should also be erased to Object, so why this is allowed? – Ankush G Mar 03 '17 at 08:44
  • 1
    Using a super bound makes perfect sense, and the quote you gave is *very* misleading. I have a class that extends `HashMap` (`MyClass extends HashMap`). If `super` were allowed here, I could assure that `MyClass` can store items with a key of `KeyType`, since the underlying HashMap's key will always be a super of `KeyType`. The idea here isn't that `X` is erased to `Vehicle`, that's what `extends` is for. We **_want_** `X` to be erased to something above (or equal) to `Vehicle` so that a `List` of type `X` inside our class can store any X we want to put into it. – Kröw Jul 12 '18 at 19:31
  • @Kröw can you give an example of what could you do with an instance of `K`, given the knowledge it is some supertype of `KeyType`? – Andy Turner Jul 13 '18 at 08:00
  • 2
    @AnkushGatfane it *is* erased to `Object`. The difference between `` and ` super Number>` is that you can't actually do anything useful with the fact it is "that type": all you would know about a `T` is that it has all of the methods that `Object` has. But *all* reference types have all of the methods that `Object` has, so you don't know anything more than if you'd just used `?`, aside from the fact that adding any instance of `Number` to that list is compatible with the expectations of the type of the elements in the list (that `Number` is a subclass of the required type). – Andy Turner Jul 13 '18 at 08:05
  • @AndyTurner Are you talking about an Object of type `K`, where `K` is a supertype of `KeyType`? I suppose I could call any methods declared in `Object`, on it, since I know it has to be an `Object`. Apart from that, there's not much you can do with the *instance*, without casting. Also, in the last sentence of my first comment, I meant to say, "...inside our class can store any `Vehicle` we want to put into it." Sorry if that caused any confusion. – Kröw Jul 13 '18 at 16:56
  • *"I meant to say, "...inside our class can store any `Vehicle` we want to put into it." Sorry if that caused any confusion."* - If that is what you are trying to express, you would express that as `X extends Vehicle`. – Stephen C Sep 18 '19 at 11:16
1

Consider this example:-

Case 1 Upper Bound:

public class Node<T extends Comparable<T>> {
    private T data;
    private Node<T> next; 
}

In this case, type erasure replaces the bound parameter T with the first bound class Comparable.

public class Node {
   private Comparable data;
   private Node next;
}

As we know the fact Parent class reference can be used to refer to a child class object.So this code is acceptable in anyhow, as the reference data can point to the instance of either Comparable or its child classes.

Case 2 Lower Bound:

If we can have code something like

public class Node<T super Comparable<T>> {
    private T data;
    private Node<T> next; 
}

In this case, Compiler can neither use Object or any other class to replace bound type T here and it is also not possible that a child class reference can be used to refer a parent class instance.

Vicky
  • 883
  • 13
  • 28