简体   繁体   中英

can getters be used in equals and hashcode?

I have below code which overrides equals() and hashcode() methods.

public boolean equals(Object obj)
 {
   if (obj == null)
     return false;
   if (!(obj instanceof Name))
     return false;
   Name name = (Name) obj;
   return this.name.equals(name.name);
 }

 public int hashCode()
 {
   return name.hashCode();
 }

here can i replace below 2 lines:

return this.name.equals(name.name);
return name.hashCode();

with

return this.getName().equals(name.getName());
return getName().hashCode();

i mean instead of using properties can i directly use getters inside equals and hashcode methods?

Thanks!

Yes sure you could use this,

hashcode() and equals() are field methods, They can access private members directly, but what if there is some logic wrapped in accessor method, so it is always safe to access fields using accessor methods

Yes, I strongly recommend using getters in equals() & hashCode() implementation. And to the best of my knowledge, this will not harm you in any manner.

The implementation of equals() without getters will fail to give you the correct result when you compare two proxied objects.

Eg: If you try comparing two proxied objects returned by your underlying hibernate dao, you'll never receive true from your equals() method, even though they're same objects.

Update

Use getter methods instead of direct access. This is because the object instance passed as other may be a proxy object, not the actual instance. To initialize this proxy, you need to access it with a getter method.

Check this for more information.

You can, but why would you? Option A: the compiler inlines that, so you end up with a reference to the field anyway. Option B: The compiler does not inline the call, ie you've introduced one extra method call.

There are also implications for legibility- if the name field is directly accessible within the class, why not refer to it directly? I find this easier to read, but some people find it inconsistent.

Yes, why would you not be able to?

In future, with things like this, I recommend you just give it a try and see.

Yes you can. Why not? What's your doubts?

No.

Fields used in hashCode() should be final value types. If they aren't, the hash of the instance can change after it has been added to a map or set which will lead to runtime errors like Map not being able to find an instance that you just put into it.

Since equals() must behave the same as hashCode() , this requirement leaks into equals() as well. Since the field is final , subclasses should not overwrite the getter, so they should be final as well.

When the getter is final , there is no point to use it in equals() / hashCode() : It's more characters to type, more code to read, makes compilation slower (the compiler must consider to inline this), might make execution slower.

For more information about the many pitfalls of equals()/hashCode(), see the excellent EqualsVerifier .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM