1

I have a question: I don't know I can't compare two different enums with == operator. This is my code:

public class EnumExercises {

enum Seasons{
    SPRING, WINTER;

    Seasons() {
        System.out.println("Hello");
    }
}

enum TestResult {
    PASS, FAIL, SPRING; 
}
public static void main(String[] args) {
    Seasons s = Seasons.WINTER;
    Seasons s2 = Seasons.SPRING;
    TestResult t = TestResult.PASS;
    System.out.println(s2==t);  //incompatible...why?
    System.out.println(s2.equals(t));


}}

Thanks a lot.

Sam
  • 536
  • 5
  • 23
  • 2
    They are of different types: TestResult and Seasons. –  Oct 27 '18 at 15:30
  • because they are enum doesnot mean they are the same type. https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals – The Scientific Method Oct 27 '18 at 15:33
  • Java Language Specification JLS 15.21.3 Reference Equality comparison (https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.21.3): **It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5). The run-time values of the two operands would necessarily be unequal.** – Thomas Kläger Oct 27 '18 at 15:36

2 Answers2

3

For the same reason you can't say

String s = "1";
int t = 1;

if (s == t) {

s2 and t are of different types. They are not comparable.

In the background, enum types compile out their names, so this wouldn't do what you want unless it coerces into compatible types. If you wanted to do this, you should use name() or toString(). See e.g. this answer.

if (s2.name().equals(t.name())) {

In general, == on objects checks if they refer to the same memory. That doesn't seem to be what you want to check here. You seem to be looking for the behavior on primitives (equal if the values are equal), which you won't get from object comparisons like this.

mdfst13
  • 850
  • 8
  • 18
3

Enum.Equals() compares two enumerations for equivalence in both type and value. Thus it is legitimate to use it on two different types of Enum. The == operator, on the other hand, compares the numeric value of the two enums and presupposes that they are of the same type. Your first test fails because Seasons and TestResult are not the same type. The latter one succeeds because they are both based on Enum type - they're just not equivalent. You can get around this if you really need to by two different techniques.

However in advance I will advise that you use these with care as they can cause all sorts of trouble later on. The enums are different types, presumably for a reason. Side-stepping that reason is a problem that begs the question "Why?". If you have an answer for that question that is legitimate, then perhaps what you should really be looking at is refactoring your code to make it unnecessary.

Now, for how to get away with comparing them anyway, I promised two methods. The first is by value. Cast both enumerations to ints and compare them by value, like ((int)s2) == ((int)t);. This is essentially the same as using the operator == except you've removed type from the comparison. The second is by meaning - compare the enumeration itself by converting them both to a string, so s2.ToString().Equals(t.ToString());. This will compare "SPRING" to "PASS", so numeric equivalency is no longer an issue.

If it should be possible to convert your two enums to each other, then perhaps what you should be looking at is explicitly doing the conversion first and then comparing them. In that way, you make your purpose clearer, which will make you a lot happier if you find yourself trying to maintain that code in a couple of years' time. It's more actual work, but it will pay dividends in readability.

YrthWyndandFyre
  • 149
  • 1
  • 3