On Feb 25, 2019, at 6:32 AM, Brian Goetz <brian.go...@oracle.com> wrote: > … > To pick up on John’s note from v-dev over the weekend, value-objects are more > easily _forgeable_ than identity-objects. There are infinitely many possible > java.lang.Integers, because of the unique-per-instance identity; there are > only finitely many instances of > > value class IntWrapper { public int i; } > > and, given access to the constructor, you can construct them all, and readily > stamp out whatever instance you like, and it is just as good as all other > instances with that state.
My current favorite metaphor for explaining the difference between value* objects and reference* objects is the one you coined, Brian, of the little band placed around the infant's wrist just after birth. Similarly the JVM adds such a unique extra identity* (what else do you call it?) to every Integer but not to any int. Values are not values because they have something different from objects, but because they don't have the wristband; you can't tell them apart anymore, compared to objects which always carry their little wristband around. (Metaphor failures: We don't use infant wristbands to *tell infants apart*. And the infant eventually loses the wristband. Tattoo? Let's not; besides those are forgeable. Regardless, the wristband is helpful.) So if an implementor wants every new value to be not-same* to every other new value, the implementor of the value* class can just add a wristband. That is: > value class UnforgeableIntWrapper { > public int i; > private Object wristband = new Object(); } And done, I hope. Does the JVM have anything to add here? I don't think so. If we were to create unforgeable value objects as a third or fourth kind of type, this is the implementation we'd use. So encapsulation, controlled by user choice, provides adequate control over this corner case in op== semantics. — John