Identity-sensitive operations include reference equality (==), identity hash-based, or synchronization.
The Optional class is a value-based class such as LocalDateTime, therefore identity-sensitive operations should be avoided.
For example, let's test the equality of two Optional classes via ==:
Book book = new Book();
Optional<Book> op1 = Optional.of(book);
Optional<Book> op2 = Optional.of(book);
// Avoid
// op1 == op2 => false, expected true
if (op1 == op2) {
System.out.println("op1 is equal with op2, (via ==)");
} else {
System.out.println("op1 is not equal with op2, (via ==)");
}
This will give the following output:
op1 is not equal with op2, (via ==)
Since op1 and op2 are not references to the same object, they are not equal so don't conform with the== implementation.
To compare the values, we need to rely on equals(), as follows:
// Prefer
if (op1.equals(op2)) {
System.out.println("op1 is equal with op2, (via equals())");
} else {
System.out.println("op1 is not equal with op2, (via equals())");
}
This will give the following output:
op1 is equal with op2, (via equals())
In the context of the identity-sensitive operations, never do something like this (think that Optional is a value-based class and such classes should not be used for locking—for more details, see https://rules.sonarsource.com/java/tag/java8/RSPEC-3436):
Optional<Book> book = Optional.of(new Book());
synchronized(book) {
...
}