Strange generated hashCode() ?
Hi All.
I spent about a day of seeking what is wrong and found out, there is a problem with eqauls/hasCode generator in IDEA (I am using 12.1.3 community edition) . What is wrong from my point of view is using super.hashCode()/equals. It seems to me, if I decided to override equals and hasCode for some classes, it means they are not suitable for me. I looked to my old project where I also used previous version of IDEA, there is no super.hashCode()/equals.
Probably I do not understand something, but I think super should no be used, what do you think? I found some similar discussion dated by 2005.
Small example where this is wrong. In my project I entended javax.management.MBeanAttributeInfo and used extended object as a key in HashMap. Because of strange implementation of MBeanAttributeInfo.equals and MBeanAttributeInfo.hashCode I had duplicated values of my extended object in Map even if I overide equals and hashCode, e.g.
public class StatAttributeInfo extends MBeanAttributeInfo {
....
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof StatAttributeInfo)) return false;
if (!super.equals(o)) return false;
StatAttributeInfo info = (StatAttributeInfo) o;
return getName().equals(info.getName());
}
public int hashCode() {
int result = super.hashCode();
result = 31 * result + getName().hashCode();
return result;
}
I had to remove lines with super.XXX to made it workable
Please sign in to leave a comment.
Hi Victor,
That calls to super class equals()/hashCode() are necessary for processing super class-scoped state.
Consider a situation like below:
When you override equals()/hashCode() at Child class you need to explicitly process super class state as well (otherwise two Child objects with the same 'j' value but different 'i' value will be considered equal).
Moreover, there is a possible case that super class' state is not exposed, i.e. the fields are private and no getters are provided.
Denis
Denis, I understand what they would like to achive, but do not understand why it should be done, I mean
"if I decided to override equals and hasCode for some classes, it means they are not suitable for me"
That is why I think it seems strange. Look at javax.management.MBeanAttributeInfo.equals and hashCode, do you think provided implementation is suitable for using in HasMap ? I do not hink so, That is why I decided to override it. Actually I do no think that in general using super.XXX in equals and hasCode is a good idea.
I think the problem is here - "if I decided to override equals and hasCode for some classes, it means they are not suitable for me" - you generalize particular use-case with jmx classes to all use-cases. Much more common scenario is that equals()/hashCode() are overridden because sub-class introduces new state.
Denis
>>>> Much more common scenario is that equals()/hashCode() are overridden because sub-class introduces new state.
Right and it should be my decision whether to use state from parent ot not. In general, I do not have access to source code and do not know how they implemented corresponding methods - I should no rely on implementation details, instead I should relay on contract.
How would you consider closed super class state at your sub-class without delegating to it's super-methods?
Denis
Hi all,
I recently came across a problem pretty much similar to Victor's.
I thought it would be really cool if IntelliJ could somehow figure out if the particular class that the user intends to automatically generate equals/hashCode is the direct descendant of Object class and if so, generates equals/hashCode in a more appropriate manner (not using super.hashCode/super.equals).
Is it technically possible?
I don't have a really deep understanding on how IDEs work, so I hope I am not asking something that is too obvious.
Thanks in advance!
please raise a feature request at https://youtrack.jetbrains.com/issues