0

So to make a long story short. A professor asked this question in class as a discussion starter. Besides the obvious

B = new SomeClass("B"); // But B can be null, can can be new SomeClass("A");
A = new SomeClass("A");
A==B

will guarantee no NPE when comparing, what are the reasons to use B==A instead of A==B?

Where A and B are of same type, and this is language independent. So you can assume A.equals(B) for Java, or equivalent syntax in C or C++ etc....

And no, this is not homework.

Churk
  • 4,556
  • 5
  • 22
  • 37
  • 2
    Each of your scenarios and languages has a very different answer. – SLaks Mar 26 '12 at 19:40
  • Using `==` (assuming it was not overloaded) will not throw in C#. – Oded Mar 26 '12 at 19:41
  • 1
    Why is this tagged both Java and C#? In Java , `==` will never throw an NEP. – NullUserException Mar 26 '12 at 19:43
  • 1
    A lot of times, people would do B==A if B is a constant. The idea behind this being, to catch the case where you accidentally put one "=" in the statement, causing an assignment instead of a check. In some languages the code running may end up different depending on if you do A==B or B==A (think about A and B being of two different types that both have the == operator overloaded, or if implemented via .Equals, A and B may have different .Equals(). – Shahar Prish Mar 26 '12 at 19:43
  • Please select a language. In Java `A == B` and `B == A` are identical, making this an extremely poor question. Also note that `==` and `.equals()` are not the same thing. Once you've done so, reply to my comment and I'll reopen this. – NullUserException Mar 26 '12 at 19:58
  • 3
    @NullUserException Maybe irrelevant to this question but when autoboxing/unboxing is involved, Java `==` can throw a NPE. – madth3 Mar 26 '12 at 20:03
  • @NullUserException ` Integer i1 = null; int i2 = 40; if (i2 == i1) { System.out.println("Iguales"); }` – madth3 Mar 26 '12 at 20:14
  • @madth3 I don't think the OP is referring to this either, but that's a definitely an interesting behavior. Thanks for teaching me something new. – NullUserException Mar 26 '12 at 20:21

5 Answers5

10

In Java, A == B and B == A always have the same semantics. In C# (which has operator overloading), there can be a difference if, say, B is an instance of a subclass of the class of A.

Note that A.equals(B) is not equivalent to A == B.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • I was actually looking for something more, but have not considered that C# == has overloading, but I'll put the subclass example to the test. But that is something I have not considered. – Churk Mar 26 '12 at 20:38
  • @Churk - One of the hazards of equality testing (as opposed to testing identity) is that subclasses can have different ideas about equality, and this can easily break commutativity. There are no good ways around this. – Ted Hopp Mar 26 '12 at 21:41
3

In C# operators are not guaranteed to be commutative as they can be overloaded, so A == B will not necessarily return the same result as B == A.

E.g.

    class Program
    {
        static void Main(string[] args)
        {
        var a = new MyClass("A");
        var b = new MyClass("B");

        Console.WriteLine(a == b);
        Console.WriteLine(b == a);

        Console.ReadLine();
    }


    public class MyClass
    {

    private string _Name;

    public MyClass(string name)
    {
        if (_FirstInstance == null)
        {
            _FirstInstance = this;
        }
        this._Name = name;
    }

    private static MyClass _FirstInstance = null;

    public static bool operator ==(MyClass left, MyClass right)
    {
        return object.ReferenceEquals(left, _FirstInstance);
    }

    public static bool operator !=(MyClass left, MyClass right)
    {
        return !(left == right);
    }
}

Yes, I realise this is insane.

Ian Newson
  • 7,679
  • 2
  • 47
  • 80
1

I think you mean .equals, not ==. a.equals(b) will throw an NPE if a is null, but not if b is null. So if you know a is not null, you should do a.equals(b) instead of the other way around.

This is not, however, language-independent. Some languages don't have null at all!

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
1

In java, you can do A == B or B == A and you won't get an NPE. The real problem is when you do

String s = ...;
boolean isNull = s.equals("myString");

instead of

boolean isNull = "myString".equals(s);

Since you're calling a method on an object, and "myString" is a properly instantiated object, then the second call will never throw an NPE regardless if the variable "s" is null or not. You don't get that guarantee with the first call, since you're not sure if the "..." on the right side of the "s" assignment is "yourString" or null.

Spencer Kormos
  • 8,381
  • 3
  • 28
  • 45
  • This is one of the obvious reasons, to ensure no NPE, but what other reason is what I am looking for. And I have talk to many who can't come up with any, and the professor is not telling. So I am very curious if there is. – Churk Mar 26 '12 at 19:47
  • Even in your edited example, there's no risk of an NPE since you're not calling a method on a possible null reference, you're just comparing two references to each other to see if they are the same. In Java the ordering won't matter with "==". – Spencer Kormos Mar 26 '12 at 19:52
0

In Java

Object a = new Object();
Object b = null;
System.out.println(a.equals(b));  //false
System.out.println(b.equals(a));  //NPE!

So if you have a known constant value it should be on the left side of the expression.

Danny
  • 7,368
  • 8
  • 46
  • 70