wyhao31
wyhao31

Reputation: 377

Why Java Enum need to check class and declaringClass in compareTo method

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

Answers (2)

Jason C
Jason C

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

Jorn Vernee
Jorn Vernee

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

Related Questions