bowbahdoe / magic-bean

A very basic library which will generate getters and setters.
Other
84 stars 10 forks source link

Code generated for equals, hashCode, toString handles the no fields case #10

Closed cranberrycheeze closed 2 years ago

cranberrycheeze commented 2 years ago

Added a solution to the following: https://github.com/bowbahdoe/magic-bean/issues/6 The code that's generated in equals, hashCode, toString delegates the call to the super class when there are no fields defined in the annotated bean. I did not find any unit tests in the project so I did not add a new dependency on a unit test framework (such as junit) therefore I tested the change manually. Let me know if you want unit tests in the project and I can add the dependency and corresponding tests.

bowbahdoe commented 2 years ago

After thinking about it for a bit more, I don't think we want super.equals or super.hashCode either.

The reason is that creates a sort of "asymmetry" in how those things are computed.

Using the same contrived apple example

@MagicBean(generateEqualsAndHashCode=true, generateAllArgsStaticFactory=true)
final class Apple extends AppleBeanOps {
    int abc;
}

If we have an Apple with the same int value, the generated equals and hashCode are based on the values contained.

var appleOne = Apple.of(123);
var appleTwo = Apple.of(123);

appleOne == appleTwo // false
appleOne.equals(appleTwo); // true
appleOne.hashCode() == appleTwo.hashCode(); // true

And if we do equals and hashCode with super.equals and super.hashCode those results will be based on the instance identity.

@MagicBean(generateEqualsAndHashCode=true, generateAllArgsStaticFactory=true)
final class Pear extends PearBeanOps {
}
var pearOne = Pear.of();
var pearTwo = Pear.of();

// what we get with super
pearOne == pearTwo // false
pearOne.equals(pearTwo); // false
pearOne.hashCode() == pearTwo.hashCode(); // false

// what we want
pearOne == pearTwo // false
pearOne.equals(pearTwo); // true
pearOne.hashCode() == pearTwo.hashCode(); // true

So I think for equals, we just want to check if it is an instanceof the same class. Then hashCode either be 1 or a sensible favorite number.

If users want the super behavior, they can get that by not asking for equals and hashCode.

cranberrycheeze commented 2 years ago

Changed the implementation to return 'true' for equals() and 1 for hashCode() for classes without fields as requested above.