Find the bug: Groovy and autogenerated equals

Take this simple Groovy class:

public class TestClass {
    String s
}

Hitting ‘autogenerate equals and hashCode’ a popular IDE generates the following code:

public class TestClass {

    String s


    boolean equals(o) {
        if (this.is(o)) return true;

        if (!o || getClass() != o.class) return false;

        TestClass testClass = (TestClass) o;

        if (s ? !s.equals(testClass.s) : testClass.s != null) return false;

        return true;
    }

    int hashCode() {
        return (s ? s.hashCode() : 0);
    }
}

At first this looks unusual but ok, but taking a closer look there is a bug in there, can you spot it? And even better: write a test for it?

Lessons learned:

  • If something looks suspicious write a test for it.
  • Question your assumptions. There is no assumption which is safe from be in question.
  • Don’t try to be too clever.

5 thoughts on “Find the bug: Groovy and autogenerated equals

  1. You can tell a Python coder didn’t design that😉 What happens when s is empty (but not null) in 2 different instances of TestClass?

    • Yes! You are right.
      Another interesting case happens when you use a Grails domain class mapped to an Oracle database: Oracle does not differentiate between null and empty Strings, hence the Groovy truth issue does not occur.

  2. The sad part is this bug has been in IntelliJ for at least a year now and I reported it to JetBrains about just as long ago and it is still not fixed.

    I know you didn’t mention it was IntelliJ but I’m about 99% sure it is.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s