## Overriding equals() and hashCode()

No. 159

 Q: Consider the following snippet:try (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 usual “==” operator only works as expected for the eight built in primitive Java™ types. With respect to class instances a variable holds a reference to an object rather than the object itself. Applying the “==” operator compares for object identity rather than object equality. Two different String instances albeit being different object instances may off course be equal with respect to their “payload” namely the strings they both represent. Comparing for object equality rather than for object identity in Java™ requires overriding the Object.equals(Object o) method. This override does exist in class String. Within the given context we may thus simply use String.equals(Object o): try (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 does == work for enum instances?
 Q: The preceding exercise Let me in, please! told us to override Object.equals(Object o) when comparing for the equality of different objects. With respect to enum instances there seems to be an exception to the rule 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 declared constructor. It is thus impossible to create new instances outside the respective enum's scope. Therefore object identity and equality of values are being guaranteed to match exactly for two arbitrary instances belonging to the same enum class: MyEnum e1 = ..., e2 = ...; // MyEnum representing some enum type final boolean objectIdentity = (e1 == e2), // Both boolean values will objectEquality = e1.equals(e2); // 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 ...