Skip to content

Conversation

@jlerbsc
Copy link
Contributor

@jlerbsc jlerbsc commented Jan 13, 2023

These modifications were made by an automatic java code remediation software. They are related to the rule S4973 "==" and "!=" should not be used when "equals" is overridden.

https://rules.sonarsource.com/java/RSPEC-1698

General rule for comparing object

It is equivalent to use the equality == operator and the equals method to compare two objects if the equals method inherited from Object has not been overridden. In this case both checks compare the object references.
But as soon as equals is overridden, two objects not having the same reference but having the same value can be equal.

Why should this rule also be applied to primitive types?

Because in the case of classes wrapping primitive types, the operation of the equality test depends on the implementation of the JVM and the optimizations that have been made.

Usage of the == and != operators for comparing the values of fully memoized boxed primitive types is permitted.
But usage of the == and != operators for comparing the values of boxed primitive types that are not fully memoized is permitted only when the range of values represented is guaranteed to be within the ranges specified by the JLS to be fully memoized.
And usage of the == and != operators for comparing the values of boxed primitive types is not allowed in all other cases.

JLS explanation is here https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.7

@aalhossary
Copy link
Member

In addition to the case of primitive values, I mentioned 3 concerns regarding the cases when one of the operands is null and the other is not here.

@jlerbsc
Copy link
Contributor Author

jlerbsc commented Jan 16, 2023

In addition to the case of primitive values, I mentioned 3 concerns regarding the cases when one of the operands is null and the other is not here.

Checking that an object is not null before invoking a method on that object is a preventative or protective measure. Your software evolves and what is true today may not be true tomorrow so this check is a protective measure.

@aalhossary
Copy link
Member

aalhossary commented Jan 17, 2023

Writing good software is like writing poetry: There are both science and art in it. Please spend some time to understand my concern(s) before replying, instead of blindly accepting any machine-proposed modifications.

Let's take the last proposed change as an example:

In the original code

if (seqClusterId.get(i) != seqClusterId.get(j)) {
    return false;
}

The if condition will test whether seqClusterId.get(i) (the 1st expression) != (is not equal to) seqClusterId.get(j) (the 2nd expression).
That is true in these 3 cases

  • 1st expression is null and 2nd expression is not null
  • 1st expression is not null and 2nd expression is null
  • 1st expression is not null and 2nd expression is not null and their values and not equal

Well,
What about the proposed update?

if (seqClusterId.get(i) != null && !seqClusterId.get(i).equals(seqClusterId.get(j))) {
    return false;
}

It will evaluate to true in these 2 cases only:

  • 1st expression is not null and 2nd expression is null
  • 1st expression is not null and 2nd expression is not null and their values are not equal

but it will evaluate to false in the case

  • 1st expression is null and 2nd expression is not null

which is a change of behavior.

@jlerbsc
Copy link
Contributor Author

jlerbsc commented Jan 17, 2023

You are right.

@jlerbsc
Copy link
Contributor Author

jlerbsc commented Jan 20, 2023

Thank you for your relevant analysis of our proposal. We are going to take your comments into consideration and adapt the way our solution works to test equality using Objects.equals method that addresses the use cases you have identified.

@aalhossary
Copy link
Member

@tmrpavan Your account looks very fresh (joined GitHub 2 weeks ago). May you please introduce yourself?
@josemduarte Is approving pull requests available to anyone, or only to people with certain privileges (e.g. write access)?

@tmrpavan
Copy link
Contributor

Hello @aalhossary,

You are right I am new to open source project. I am Java Backed Developer with around 3 years of experience. I was going through the PR. I felt the changes are valid. So I approved.

I think approve option is available for all.

@tmrpavan
Copy link
Contributor

Hello @aalhossary,

I would like to contribute to the project. Please let me know if any issue ore features that i can work on it.

@tmrpavan
Copy link
Contributor

image

@tmrpavan
Copy link
Contributor

@aalhossary
Copy link
Member

Hi @tmrpavan!
Welcome. We always welcome new committers.

as you found that the changes are valid, but there was an ongoing discussion about it, you should have joined the discussion and add a comment instead of rushing into doing the actions.
I advise you to read the discussion on THE CURRENT page (especially this comment).

tmrpavan added a commit to tmrpavan/biojava that referenced this pull request Apr 16, 2023
@tmrpavan
Copy link
Contributor

@aalhossary Please see this PR #1060

We can use Objects.equals(seqClusterId.get(i), seqClusterId.get(j) to full fill your needs.

Please see the below image and article to know why we can not user == or != or objects.

https://javarevisited.blogspot.com/2010/10/what-is-problem-while-using-in.html#ixzz7yTZDXO94https://javarevisited.blogspot.com/2010/10/what-is-problem-while-using-in.html#axzz7yTYv7igN

image

@tmrpavan tmrpavan mentioned this pull request Apr 18, 2023
@josemduarte
Copy link
Contributor

Closing in favour of #1060

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants