1

I wrote a class Fruit which implements the Comparable interface and 2 subclasses: Apple and Orange. I wrote a method that returns the maximum between 2 fruits (whatever it means).

Note that I did NOT use any wildcards with super.

I thought that the method max would fail because the Comparable interface is not implemented directly by Apple or Orange.

Question: Why is it suggested to use this form of wildcard:

<T extends Comparable<? super T>>

if it works also without super?

Here is the code:

package main;

//Note that I did not use the super wildcard: <T extends Comparable<? super T>>
class Max {

  public static <T extends Comparable<T>> T getMax(T x, T y) {
    return x.compareTo(y) >= 0 ? x : y;
  }
}

class Fruit implements Comparable<Fruit> {
    public String name;

    public Fruit(String name) {
        this.name = name;
    }

    @Override
    public int compareTo(Fruit other) {
        return name.compareTo(other.name) == 0 ? 0 :
               name.compareTo(other.name) > 0 ? 1 : -1;
    }

}

class Apple extends Fruit {
    String name;

    public Apple(String name) {
        super(name);
    }

}

class Orange extends Fruit {
    String name;

    public Orange(String name) {
        super(name);
    }

}

public class Main {

    public static void main(String[] args) {

        Apple a = new Apple("apple");
        Orange o = new Orange("orange");
        Fruit f = Max.getMax(a, o); //It should not be allowed because T does not implement Comparable directly
        System.out.println(f.name);

  }
}
Kami
  • 1,079
  • 2
  • 13
  • 28
  • The only worrying thing is the extraneous `name` field in the child classes, that remain null, and hide `Fruit.name`. You should make the field final as in `protected final String name;` in Fruit, so it cannot be changed and the Comparable contract remains sound. – Joop Eggen Jul 08 '14 at 10:44
  • possible duplicate of [What is super T> syntax?](http://stackoverflow.com/questions/2827585/what-is-super-t-syntax) – Harry Blargle Jul 08 '14 at 11:30

2 Answers2

2

In your case, T can be chosen to be Fruit, and the statement Fruit f = Max.getMax(a, o); would type-check correctly. Therefore, it works.

Max.getMax() has parameter types T, and instances of subtypes of T are also instances of T, so the method accepts any subtypes of T as arguments.

Note, however, that your method still has the problem that T can only be inferred to be Fruit, and not Apple, so you cannot return an Apple:

Apple a = Max.getMax(apple1, apple2);

However, consider something where the T is a generic type parameter:

public static <T extends Comparable<T>> T getMax(List<T> xs) {
  //...
}

Generics are not covariant, so this method can only accept List<Fruit>, but not List<Apple> or List<Orange>, even though Apples can compare to Apples, etc.

If you change it to:

public static <T extends Comparable<? super T>> T getMax(List<T> xs) {
  //...
}

then it work would for List<Apple> and List<Orange>.

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

As Fruit implements Comparable and Apple and Orange extend Fruit then they simply inherit the compareTo implementation from Fruit.

You could override that compareTo method in the Apple and Orange subclasses if you wished.

I think it is your understanding of inheritance here rather than your understanding of the > symbol.

<T extends Comparable<? super T>>

Here you are defining that the type T extends Comparable, so you can safely call the compareTo method on the objects.

Both objects you passed to the method DO extend comparable (as they extend Fruit which implements Comparable)

cowls
  • 24,013
  • 8
  • 48
  • 78
  • Sorry, maybe my question was not clear. Why is this wildcard always suggested > ? if it works nevertheless? – Kami Jul 08 '14 at 10:37
  • That simply tells the compiler to only allow objects that extend the COmparable interface to be passed into that method. Without it you couldnt call the compareTo method as you wouldnt know if the parameter implemented it. But all your objects do implement it. – cowls Jul 08 '14 at 10:41
  • So, was my accepted answer to my previous question wrong? Here is the link: https://stackoverflow.com/questions/24609278/java-wildcards-with-super – Kami Jul 08 '14 at 10:41
  • The other question seems right, it is just the nuance between `? super T` and `T` causing confusion here I think, question posted by @ShivamVerma seems like it will help – cowls Jul 08 '14 at 10:46
  • Sorry, it must be my fault. but I still do not get that nuance. I literally tried that example of my previous question: stackoverflow.com/questions/24609278/java-wildcards-with-super which you state as correct. It is obvious that in >, T inherits the compareTo method. I means it is always like this if you use extends. That's why I feel that the super keywords makes no sense. But again it is probably my fault that I do not get it. I try to read it again... – Kami Jul 08 '14 at 11:05