This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 181979

Summary: Generated code for "equals" can be improved
Product: java Reporter: vieiro <vieiro>
Component: EditorAssignee: Dusan Balek <dbalek>
Status: NEW ---    
Severity: normal    
Priority: P3    
Version: 6.x   
Hardware: All   
OS: All   
Issue Type: ENHANCEMENT Exception Reporter:

Description vieiro 2010-03-13 16:35:18 UTC
I've "inserted code" for "equals and hashcode" and I get:

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


I think that the

  getClass() != obj.getClass()

statement should read

  !getClass().equals( obj.getClass() )

just in case the classes come from different classloaders, for instance.

I'd also suggest making the code more succint:

  @Override
  public boolean equals(Object obj)
  {
    if (obj == null && ! getClass().equals( obj.getClass() ) )
    {
      return false;
    }
    ...
Comment 1 vieiro 2010-03-13 16:44:27 UTC
Hi again,

As you may know there's some debate on the use of "getClass()" or "instanceof" out there [1]. Intellij IDEA follows the getClass() approach too. So do I. Josh Bloch prefers instanceof [2]

Anyway I think it's honest to let the user know about this debate and to let her choose whatever approach best suits her needs. If the user is building Hibernate objects, for instance, using "instanceof" may be a better choice. 

Adding some javadoc (or some comments to the generated code) could be another enhancement.

[1]
http://cwmaier.blogspot.com/2007/07/liskov-substitution-principle-equals.html

[2]
http://www.artima.com/intv/bloch17.html
Comment 2 vieiro 2010-03-13 16:50:06 UTC
I was meaning

if (obj == null || ! getClass().equals( obj.getClass() ) )

of course.
Comment 3 Jan Lahoda 2010-03-14 15:56:27 UTC
Re using !getClass().equals( obj.getClass() ) instead of getClass() != obj.getClass(): there is no difference between these two - the equals method is not overridden for java.lang.Class, and so the default equals implementation is used (which checks for object equality). Classes loaded by different loaders are not equals to each other, and in fact if you have object o of type a.A loaded by ClassLoader A, and class a.A loaded by ClassLoader B, o cannot be casted to the class loaded by classloader B.

Re more succinct code: yes, that could be done.

Re using getClass() vs. instanceof: bug #156994 is mostly about that.

Thanks for the report.
Comment 4 swpalmer 2014-03-03 19:07:26 UTC
Note that in NB 8.0 RC1 the generated equals method is created and then a hint is marked in the gutter for the generated code that says "The if statement is redundant"
Consider the method generated for a simple key/value Pair class:

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final Pair other = (Pair) obj;
		if (!Objects.equals(this.key, other.key)) {
			return false;
		}
		if (!Objects.equals(this.value, other.value)) { // <<< here
			return false;
		}
		return true;
	}

accepting the hint leads to:

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final Pair other = (Pair) obj;
		if (!Objects.equals(this.key, other.key)) {
			return false;
		}
		return Objects.equals(this.value, other.value);
	}

Not critical, but it is irritating to see hints on generated code.
Comment 5 martijnburger 2017-02-03 09:13:25 UTC
In version 8.2 the issue is still there. We still have to change the generated equals method, because of the warning, after the method has been generated.