-3

I am new to java and I read many articles on the net about ? super T or ? extends T but I still don't get it. Here is my example:

public class A<T> {

    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public void doExtends(A<? extends T> b) {
        T t = b.getT();      //ok
        this.setT(b.getT()); // ok
        b.setT(this.getT()); // error
    }
    public void doSuper(A<? super T> b) {
        T t = b.getT();       // error
        this.setT(b.getT()); // error
        b.setT(this.getT()); // ok
    }
}

why are there errors? my question is different then the one referenced in comments

  • What errors? can you please show us the stack trace? – ItamarG3 Jul 26 '17 at 10:53
  • @ItamarG3 read my commends in code.. it wont compile – user8354588 Jul 26 '17 at 10:53
  • But what's the type of the exception? I noticed what lines are causing this, but I can't know exactly which Exception is being thrown. Btw, don't worry about the downvotes. If you read (future tense) the [ask] page, then I'm sure it would happen less in future questions you post – ItamarG3 Jul 26 '17 at 10:54
  • @ItamarG3 There are no exception thrown, OP has compile errors. – Tom Jul 26 '17 at 10:55
  • In doSuper b.getT() returns a super type to T, it might be an Object. You can add `T`s to it, but you cannot get a `T` out. – matt Jul 26 '17 at 10:55
  • Please include the compiler error message – NickJ Jul 26 '17 at 10:55
  • @ItamarG3 i read that article but its not helping me – user8354588 Jul 26 '17 at 10:57
  • why -2 points? whats wrong with my question.. I am not using List.. this question is different – user8354588 Jul 26 '17 at 10:58
  • @user8354588 did you read the answer? because the **answer** would be almost the same. – ItamarG3 Jul 26 '17 at 11:01
  • @ItamarG3 I read it yesterday and its not the same to me – user8354588 Jul 26 '17 at 11:05
  • @user8354588 first, it's best not to *demand* anything, and\or to be rude. Secondly, it doesn't work because `b` ***is not related to*** `T`. Its generic type (the type inside the `<>`) is `T`, but it is not `T`. – ItamarG3 Jul 26 '17 at 11:27

1 Answers1

3

The thing is as follows:

In doExtends(A<? extends T> b) you specify that b is of type A encapsulating something that may be an unknown subclass of T. As such it is perfectly fine to do T t = b.getT() since b.getT() produces something extends T (so you can cast to T). Same holds true for this.setT(b.getT()) - equivalent to this.setT(t). Now let's look at the method's last line b.setT(...). As said before A contains an unknown subclass of T. But you want to stuff in a T (this.getT() produces T) and you cannot be sure that your T matches the subclass that may be inside b - that's why it doesn't work.

Next on to doSuper(A<? super T> b) - here b contains an unknown superclass of T or maybe T itself. That's why the last line - setting the value - is perfectly fine. this.getT() produces a T which you can always cast to any of the superclasses. However when you get the value with b.getT() you only known that it's an unknown superclass of T but not guaranteed to be a T. You essentially don't know what class it will be.

Michael Rose
  • 7,220
  • 3
  • 20
  • 26