RSPEC-3437 should check how the object of value is used

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.

Hello @sebastian-toepfer ,

Thank you for the report.

This rule is very particular and probably does not apply to most developers. It focuses on what may happen when using reference equality directly or indirectly in conjunction with value-based classes and serialization. For a static analyzer, it is very difficult to determine how an object is used for certain, and the usage may change in the future.

The rule is disabled by default (it is not included in the default Sonar way quality profile). This is done for good reason: it is not applicable to most developers and may only be helpful in very specific cases.

My recommendation here is to disable this rule again, as it does not appear to apply to your use case.

thanks for your response. But I not understand why this rule. why not check if someone use == for value type?

and thanks a lot for the hint that it was disabled at default. must found the activator now :slight_smile:

In general, determining how a value will be used throughout the application is not trivial. You need to employ techniques such as data flow analysis to achieve this, which S3437 doesn’t currently use. While this is theoretically possible, we see other rules and features we can work on that will ultimately bring more value than this rule.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.