Then tell us:
- What language is this for?
Java
- Which rule?
RSPEC-3437
- Why do you believe it’s a false-positive/false-negative?
private class Person implements Serializable {
private final String name;
private final LocalDate bithday;
public Person(final String name, final LocalDate bithday) {
this.name = Objects.requireNonNull(name);
this.bithday = Objects.requireNonNull(bithday);
}
public boolean isYourBirthdayOn(final LocalDate date) {
return bithday.equals(date);
}
@Override
public String toString() {
return "Person{" + "name=" + name + ", bithday=" + bithday + '}';
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + Objects.hashCode(this.name);
hash = 79 * hash + Objects.hashCode(this.bithday);
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (!Objects.equals(this.name, other.name)) {
return false;
}
return Objects.equals(this.bithday, other.bithday);
}
}
sonar means that I should make birthday transient, for something that is not done here.
Test to check what happens after serializaion of two Persons which are equals but not the same instance:
try (final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(personBytes))) {
final Person person1 = Person.class.cast(ois.readObject());
final Person person2 = Person.class.cast(ois.readObject());
assertThat(person1, is(not(sameInstance(person2))));
assertThat(person1.isYourBirthdayOn(birthdayOfPerson), is(true));
assertThat(person1, is(person2));
}
if i apply the transient hint → this test fail at
assertThat(person1.isYourBirthdayOn(birthdayOfPerson), is(true));
because the deserialized person does not have any birthday anymore. (okay this can also be happen if one use invalid data at deserialization, but think is another issue).
The transient field will than be covered by another rule, which destroy the immutable desgin.
Sonar should check how valueobjects been used instead of say it should not be serialize! Learn from Integer, where
assertThat(Integer.valueOf(127) == Integer.valueOf(127), is(true));
but
assertThat(Integer.valueOf(128) == Integer.valueOf(128), is(false));
- Are you using
SonarCloud
code above.
Hope this was okay to post it here, have not found any better place.