For regular types (including String):
==
compares object references. It tests if two object references are equal; i.e. if they refer to the same object.
equals(Object)
tests if this object is "equal to" another one. What "equal to" means depends on how the object's class defines equality. The java.lang.Object
class defines equals(other)
to be this == other
, but many classes override this definition.
toString()
provides a simple conversion of the object to a String. The format and content of the resulting String is class specific, and (from the perspective of the java.lang.Object
contract) there are no guarantees that it will be meaningful.
For (true) primitive types:
==
compares values of the type, and
equals()
and toString()
are not defined. Java does not allow you to call a method on a primitive value.
However this is complicated by the fact that in some contexts the Java language says that a primitive type can be "autoboxed" to give an instance of the primitive type's corresponding wrapper type; e.g. int
corresponds to java.lang.Integer
, and so on. For the wrapper classes:
==
is defined the same as for any other reference type,
equals()
compares the wrapped values, and
toString()
formats the wrapped values.
The spanner in the works is illustrated by the following:
int a = ...
int b = a;
Integer aa = a; // autoboxing occurs
Integer bb = b; // autoboxing occurs
assert a == b; // always succeeds
assert aa.equals(bb); // always succeeds
assert aa == bb; // sometimes succeeds, sometimes fails.
The reason that the last sometimes fails is that the JLS does NOT guarantee that autoboxing a given primitive value will always give the same wrapper object. It will in some cases (e.g. for small integers), and won't for others (e.g. large integers).
The lesson to be learned from the example above is that you need to be very careful about using ==
on a reference type. Only use it when you really want to test if two references are to the same object. Don't use it if you just want to test if the objects are "equal" without the overhead of calling equals()
.
(Also note that String
is another type where ==
is going to give you the wrong answer in many situations; see How do I compare strings in Java?.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…