简体   繁体   中英

Do two equal objects have to have the same toString output?

Do two equal objects have to have the same toString output?

In code, does the following have to hold in general?

if(o1.equals(o2))
  return o1.toString().equals(o2.toString()) // always true?

I am asking because I have just written a toString method for which the above statement does not hold. I could not find any hint at the documentation, but I want to get sure my toString method does not break any contract rules.

No, they do not have to have the same toString() output in order to be equal. There is no contract in Java that states the equals() method must be true for both the object itself and its toString() method.

The only contract equals() has with other methods is with hashCode() :

Note that it is generally necessary to override the hashCode method whenever this method [equals] is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

The contract it has irrespective of other methods is:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.

  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.

  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

  • For any non-null reference value x, x.equals(null) should return false.

Source: https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-

Edit: Some people are saying Effective Java by Joshua Bloch says the toString() method should use the same fields as the equals() method. This is not true. He states:

While it isn't as important as obeying the equals and hashCode contracts (Item 8, Item 9), providing a good toString implementation makes your class much more pleasant to use.

What he classifies as a "good implementation" is:

When practical, the toString method should return all of the interesting information contained in the object, as in the phone number example just shown. It is impractical if the object is large or if it contains state that is not conducive to string representation. Under these circumstances, toString should return a summary such as “Manhattan white pages (1487536 listings)” or “Thread[main,5,main]”.

So no, it in no way relates to the equals() method.

There is no requirement for this. There is a dependency between equals and hashCode : equal objects must return the same hashCode value. toString is only used for printing the object.

There is no contract for toString, only for equals and hashCode. And from my point of view it also doesn't make sense.

Imagine o1 and o2 are of class Person{}, then you get only the string of the reference.

There's no "requirement" that hashCode match equals , only a best practice that it do so, or your program won't make sense. Same with toString . It should be consistent with equals , as should compareTo if used. See Effective Java by Joshua Bloch for the rationale. People who tell you otherwise need to read that book because they're mistaken.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM