Why is it legal to create new Box();
and new Box<Integer>();
? Is it because Box
is comparable?
public class Box<Comparable> { private boolean compareTo(Box b) { return (this.y > b.y); } double x=0; double y=0; public static void main (String[] args) { Box a = new Box(); Box b = new Box<Integer>(); System.out.println(a.compareTo(b)); } }
Advertisement
Answer
You have declared the class with a generic type parameter. This is not the same as implementing the Comparable interface:
public class Box<Comparable> { }
Is the same as:
public class Box<T> { }
Which is not the same as:
public class Box<T> implements Comparable<T> { @Override public int compareTo(final T o) { return 0; } }
Because the type parameter is unbounded, it will accept any type. So you can use an Integer
or a String
:
public class Box<T> { public static void main(String[] args) { Box a = new Box(); Box b = new Box<>(); Box c = new Box<Integer>(); Box d = new Box<String>(); } }
The reason why you can create a new Box
without specifying the type is because of backwards compatibility. The new Box
would have the raw type Box<T>
. It is bad practice and should be avoided.
You can read more about Raw Types here
If you wanted to enforce that the type parameter implements Comparable, then you can do:
import java.awt.*; public class Box<T extends Comparable<T>> { public static void main(String[] args) { Box a = new Box(); Box b = new Box<>(); Box c = new Box<Integer>(); Box d = new Box<String>(); // This one will not work as Rectangle does not implement Comparable! Box e = new Box<Rectangle>(); } }