Reputation: 377
Type parameter E
in Enum is defined as <E extends Enum<E>>
. So why in Enum implementation source code, we still need to check getClass()
and getDeclaringClass()
in compareTo
method? I don't think compiler can pass when I set a different enum type object in compareTo
.
Upvotes: 3
Views: 390
Reputation: 40335
It covers the case of comparing raw types and values obtained via unsafe / unchecked casts and conversions (such as Comparable
, or Object a
):
static enum Fruit { Apple, Orange, Banana };
static enum Animal { Cat, Dog, Horse };
public static final void main (String[] args) throws Exception {
Enum f = Fruit.Apple;
Enum a = Animal.Cat;
f.compareTo(a);
}
There, compareTo
would fail with a ClassCastException
at the explicit getDeclaringClass
comparison, as it would pass the first explicit cast (Enum other = (Enum)o
) with no issue.
As for comparing getClass
, it's tagged as an "optimization" in that source. The reason this is an optimization is that if the value classes are the same, then they're definitely from the same enum, and so there's no need to call the slightly more expensive getDeclaringClass
. Since the vast majority of enums are likely simple enums (no value class bodies), it's optimized for that case.
Upvotes: 7
Reputation: 33865
It can, if you use Enum
as a raw type. For instance in this program:
public static void main(String[] args) {
Enum e = A.x; // All occurrences of E are erased to Enum
e.compareTo(B.i); // B.i extends Enum, so this is fine
}
enum A {x,y,z};
enum B {i,j,k};
Upvotes: 4