## Overriding equals() and hashCode()

No. 164

 Q: Consider the following snippet:final Scanner scan = new Scanner(System.in)); do { System.out.print("Please enter password: "); final String password = scan.nextLine(); if (password == "secret") { break; // Leave enclosing do ... while loop } else { System.out.println("Sorry, please try again"); } } while (true); System.out.println("You made it!"); // ...Describe the above code's intended behaviour. Will it succeed? Execute the above code and provide a clue for correcting the underlying flaw. A: The user is being asked for a password. Only when entering "secret" access shall be granted. Unfortunately comparing the user's input and the corresponding password is seriously flawed: ... if (password == "secret") ...On execution the string literal "secret" will be represented as a String object in memory. Each new user input string will be represented as a different String object in memory as well. Unfortunately the “==” operator only works as expected for the eight built in primitive Java™ types. With respect to class instances variables hold references to objects rather than to the objects' values. The “==” operator compares for object identity rather than for object equality. Two different String instances may off course be equal with respect to their “payload” namely the values they both represent. Comparing for object equality rather than for object identity in Java™ requires using the equals(...) method instead. A prerequisite for this to work requires the class authors overriding the Object.equals(Object o) method accordingly. This override does exist in class String. Within the given context we may thus simply use String.equals(Object o): final Scanner scan = new Scanner(System.in)); do { System.out.print("Please enter password: "); final String password = scan.nextLine(); if (password.equals("secret")) { break; // Leave enclosing do ... while loop } else { System.out.println("Sorry, please try again"); } } while (true); System.out.println("You made it!"); // ...
### Why is == correctly comparing enum instances?
 Q: The preceding exercise Let me pass, please! told us to override Object.equals(Object o) when comparing different objects for equality. The == operator in general does compare for object identity but two different objects may still be considered equal e.g. with respect to their attributes. However comparing Enum instances for equality using the == operator seems to be sufficient e.g.: Day day = Day.Saturday; // Sufficient using operator == ? if (day == Day.FRIDAY) ... // Or do we require equals? if (day.equals(Day.FRIDAY)) ...Do we thus require an equals(Object o) method for comparisons? Give a precise explanation. A: In case of enum instances using the “==” operator is sufficient. Due to the way enum's are being constructed instance creation is being limited to the underlying enum's scope by its implicitly private constructor. It is thus impossible creating new instances outside the respective enum's scope. Therefore for any two given enum instances both object identity and equality of their respective values is being guaranteed to yield the very same result: MyEnum instance1 = MyEnum.x, // MyEnum representing instance2 = MyEnum.y; // some enum type. final boolean objectIdentity = (instance1 == instance2), // Both boolean values will objectEquality = instance1.equals(instance2); // always be equal.As an aside: In case of null values using the “==” operator avoids java.lang.NullPointerException problems: Day day = null; if (day == Day.FRIDAY) ... // Just different, no problems if (day.equals(Day.FRIDAY)) ... // Oops: NPE approaching ...