4

I let Eclipse generate the equals method for my class and it starts with:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (getClass() != obj.getClass())
        return false;
[...]

It seems to me, a check like if (obj == null) return false; is missing. Otherwise, if a null reference is passed to equals there will be a null pointer exception in obj.getClass(). Am I wrong or is Eclipse wrong?

Ishtar
  • 11,542
  • 1
  • 25
  • 31
stracktracer
  • 1,862
  • 5
  • 24
  • 37

6 Answers6

4

Perhaps you are having an old eclipse version. My eclipse generates this:

if (this == obj)
    return true;
if (obj == null)
    return false;
if (getClass() != obj.getClass())
    return false;
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Still using Helios, maybe that's the reason. – stracktracer Sep 27 '11 at 14:29
  • It has been correct at least since 3.2. Something else is likely to be the problem – Bozho Sep 27 '11 at 14:30
  • Is there a way to modify the "equals" generation? Maybe it has been done here at the company? – stracktracer Sep 27 '11 at 14:34
  • http://stackoverflow.com/questions/6255210/how-to-customize-hashcode-and-equals-generated-by-eclipse http://stackoverflow.com/questions/2512916/generating-custom-methods-in-eclipse – Bozho Sep 27 '11 at 14:42
  • 1
    So, the behavior of the menu item "Source, generate hashCode() and equals()" cannot be changed. I confirm now that Helios creates the null check. Found it missing when reviewing my colleague's code who pretended he created it with eclipse. Either his version is very old the null check got somehow deleted. – stracktracer Sep 27 '11 at 14:51
2

You are right, if Eclipse does it that way. But it doesn't. On my machine, Eclipse Indigo / Ubuntu, given this Class:

public class Foo {
    private String bar;
}

Eclipse would generate the following equals() method:

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    Foo other = (Foo) obj;
    if (bar == null) {
        if (other.bar != null) return false;
    } else if (!bar.equals(other.bar)) return false;
    return true;
}

For comparison, here's the equals() method I would write for the same class (using Guava):

@Override
public boolean equals(final Object obj) {
    return obj instanceof Foo ? Objects.equal(bar, ((Foo) obj).bar) : false;
    //          ^--- implicit null check here
}

I use this Eclipse code template to achieve this:

${:import(com.google.common.base.Objects)}
@Override
public boolean equals(final Object obj){
    return obj instanceof ${enclosing_type} ? Objects.equal(${field1:field}, ((${enclosing_type}) obj).${field1}) : false;
}

@Override
public int hashCode(){
    return Objects.hashCode(${field1});
}

@Override
public String toString(){
    return MoreObjects.toStringHelper(this).add("${field1}", ${field1}).toString();
}

Unfortunately, I have to keep one of these around for each cardinality of fields, so I have templates named eq1 (the above), eq2, eq3, eq4 etc. It's a small nuissance, but it's still a lot better than the monster methods generated by Eclipse. Guava docs

facundofarias
  • 2,973
  • 28
  • 27
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
0

Yes, passing null as obj would give a NullPointerException with that code.

jornb87
  • 1,441
  • 10
  • 15
0

You indeed need a null check. My version of Eclipse generates equals methods with a null check.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
0

if (obj) is null, the obj.getClass() will throw an NPE

ben_muc
  • 211
  • 3
  • 6
0

It seems to me, a check like if (obj == false) return false; is missing.

Why do you want to compare object with a Boolean value? ;-)

I suppose you though about obj == null check, and that is exactly what Eclipse generates in my case:

@Override
      public boolean equals(Object obj)
      {
        if (this == obj)
          return true;
        if (obj == null)
          return false;
        if (getClass() != obj.getClass())
          return false;
        TestGetClass other = (TestGetClass) obj;
        if (id != other.id)
          return false;
        return true;
      }

I am using 3.7 version. Anyway, you are right... actually Eclipse... too ;-)

mikus
  • 3,042
  • 1
  • 30
  • 40