Value-based Classes

Some classes, such as java.lang.Integer and java.time.LocalDateTime, are value-based. Value-based classes:
  • declare only final instance fields (though these may contain references to mutable objects);
  • declare implementations of equals, hashCode, and toString which are computed solely from the instance's state and not from its identity or the state of any other object or variable;
  • have instances that are freely substitutable when equal, meaning that interchanging any two instances x and y that are equal according to equals() produces no visible change in the behavior of the class's methods;
  • perform no synchronization on an instance's intrinsic lock;
  • do not have (or have deprecated any) accessible constructors;
  • may support instance creation through factory methods that do not promise a unique identity for each invocation—in particular, each factory method must allow for the possibility that if two independently-produced instances are equal according to equals(), they may also be equal according to ==;
  • are final;
  • extend either Object or a hierarchy of abstract classes that declare no instance fields or instance initializers and whose constructors are empty.

When two instances of a value-based class are `equal`, a program should not attempt to distinguish between their identities, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization, or any other identity-sensitive mechanism.

Synchronization on instances of value-based classes is strongly discouraged, because the programmer cannot usually guarantee unique ownership of the associated lock.