Value-based Classes confusion

Viewed 3419

I'm seeking some clarification to the definition of Value-based Classes. I can't imagine, how is the last bullet point (6) supposed to work together with the first one

  • (1) they are final and immutable (though may contain references to mutable objects)
  • (6) they are freely substitutable when equal, meaning that interchanging any two instances x and y that are equal according to equals() in any computation or method invocation should produce no visible change in behavior.

Optional is such a class.

Optional a = Optional.of(new ArrayList<String>());
Optional b = Optional.of(new ArrayList<String>());
assertEquals(a, b); // passes as `equals` delegated to the lists

b.get().add("a");

// now bite the last bullet
assertTrue(a.get().isEmpty()); // passes
assertTrue(b.get().isEmpty()); // throws

Am I reading it incorrectly, or would it need to get more precise?

Update

The answer by Eran makes sense (they are no more equal), but let me move the target:

...
assertEquals(a, b); // now, they are still equal
assertEquals(m(a, b), m(a, a)); // this will throw
assertEquals(a, b); // now, they are equal, too

Let's define a funny method m, which does some mutation and undoes it again:

int m(Optional<ArrayList<String>> x, Optional<ArrayList<String>> y) {
    x.get().add("");
    int result = x.get().size() + y.get().size();
    x.get().remove(x.get().size() - 1);
    return result;
}

It's strange method, I know. But I guess, it qualifies as "any computation or method invocation", doesn't it?

5 Answers
Related