Why is it legal to create new Box();
and new Box<Integer>();
? Is it because Box
is comparable?
JavaScript
x
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:
JavaScript
public class Box<Comparable> {
}
Is the same as:
JavaScript
public class Box<T> {
}
Which is not the same as:
JavaScript
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
:
JavaScript
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:
JavaScript
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>();
}
}