Reputation:
As a kind of follow up to the question titled "Difference Between Equals and ==": in what kind of situations would you find yourself testing for reference equality in Java / C#?
Upvotes: 7
Views: 576
Reputation: 1895
Try to avoid == with objects that are normally defined with final static and then passed as members in classes that are serialized.
For example (before we had enums) I had a class defined that simulated the idea of an enumeration. Since the constructor was private and all allowed instances were defined as final statics I wrongly assumed that == was always safe to use on these objects.
For example (typing code without compiling, so excuse me if there are some issues with the code)
public class CarType implements Serializable {
public final static CarType DODGE = new CarType("Dodge");
public final static CarType JEEP = new CarType("JEEP");
private final String mBrand;
private CarType( String pBrand ) {
mBrand = pBrand;
}
public boolean equals( Object pOther ) {
...
}
}
The CarType instances were serialized when used in other objects... but after materialisation (on a different JVM instance) the == operation failed.
Upvotes: 1
Reputation: 87533
Consolidating answers ...
When, typically, do you use == equality on a reference typed variable in Java / C#?
1. To check for null:
if (a == null) ...
2. For efficiency when you are constructing an equals implementation:
boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
// Some people would prefer "if (!(o instanceof ClassName)) ..."
if (getClass() != o.getClass()) return false;
// Otherwise, cast o, leverage super.equals() when possible, and
// compare each instance variable ...
3. For efficiency when you are comparing enums or comparing objects of a class designed such that comparing object identity is equivalent to checking object equivalence (e.g. Class objects):
enum Suit { DIAMONDS, HEARTS, CLUBS, SPADES }
class SomeCardGame {
...
boolean static isATrumpCard(Card c) {
return (c.getSuit() == TRUMP_SUIT);
}
}
4. When you really intend to check object identity, not object equivalence, e.g. a test case that wants to make sure a class isn't giving up a reference to an internal data structure instance.
boolean iChoseNotToUseJUnitForSomeReasonTestCase() {
final List<String> externalList = testObject.getCopyOfList();
final List<String> instanceVariableValue =
getInstanceVariableValueViaCleverReflectionTrickTo(testObject, "list");
if (instanceVariableValue == externalList) {
System.out.println("fail");
} else {
System.out.println("pass");
}
}
Interestingly, for point #3, one article suggests using equals is safer than using .equals() because the compiler will complain if you attempt to compare to object references that are not of the same class (http://schneide.wordpress.com/2008/09/22/or-equals/).
Upvotes: 6
Reputation: 40393
My personal preference (C#) is to always leave == to mean reference equality (referring to the same object). If I need logical equivalence, I'll use Equals<T>. If I follow this rule uniformly, then there's never any confusion.
Upvotes: 0
Reputation: 49544
In C#, the == operator may be overloaded, which would mean that you can compare reference types for LOGICAL equality.
Any time the implementer of a class thought that it would be logical to compare equality, you may do so using their methods.
This being said, be careful when checking if (a == b)
in C#. This MAY be a reference equals, or it MAY be a logical comparison.
In order to keep the two cases distinct, it could be a good idea to use the two following methods, just to be clear:
object.ReferenceEquals(a, b)
a.Equals(b)
The first one is a reference comparison, and the second is usually a logical one.
here is a typical == overload, just for reference:
public static bool operator ==(RRWinRecord lhs, RRWinRecord rhs)
{
if (object.ReferenceEquals(lhs, rhs))
{
return true;
}
else if ((object)lhs == null || (object)rhs == null)
{
return false;
}
else
{
return lhs.Wins == rhs.Wins &&
lhs.Losses == rhs.Losses &&
lhs.Draws == rhs.Draws &&
lhs.OverallScore == rhs.OverallScore;
}
}
Upvotes: 1
Reputation: 40336
Because it's so fast and simple, ==
is routinely part of the Equals()
function. If two objects are ==
, then they're Equals
, and you don't need any further processing. For primitives in Java, ==
is your only option (I don't think that's true of C#, but am not sure). I'll use ==
to test for null (although more frequently it's !=
). Other than that... Stick with Equals()
. It's rare and probably a sign of trouble to need ==
over Equals
.
Upvotes: 2
Reputation: 118631
Basically, you can use == when you "know" that "==" is equivalent to ".equals" (in Java).
By doing so, you can gain performance.
A simple example where you'll see this is in a .equals method.
public boolean equals(Object o) {
// early short circuit test
if (this == o) {
return true;
}
// rest of equals method...
}
But in some algorithms, you have good knowledge of the objects you're working with, so you can rely on == for tests. Such as in containers, working with graphs, etc.
Upvotes: 0
Reputation: 91881
For Java, most commonly to see if a reference is null:
if (someReference == null) {
//do something
}
It is also pretty common with enums, but the most common place to use it that I've seen is in a properly implemented equals method. The first check will check for reference equality and only do the more expensive calculation if that returns false.
Upvotes: 5
Reputation: 7168
You can use it for quick equality checks.
For example if you are doing a compare with some very large objects that may take a while to iterate through, you can save time to see if they are referring to the same object first
Compare(LargeObj a, LargeObj b) {
if (a == b)
return true;
// do other comparisons here
}
Upvotes: 1