rspec/rules/S2154/java/rule.adoc
Marco Kaufmann 417d2d9651
Modify rule S2154: reworked rule description for LayC format [SONARJAVA-4490] (#2598)
Co-authored-by: Dorian Burihabwa <75226315+dorian-burihabwa-sonarsource@users.noreply.github.com>
2023-07-21 17:09:19 +02:00

87 lines
2.8 KiB
Plaintext

== Why is this an issue?
Using boxed values in a ternary operator does not simply return one operand or the other based on the condition.
Instead, the values are unboxed and coerced to a common type, which can result in a loss of precision when converting one operand from `int` to `float` or from `long` to `double`.
While this behavior is expected for arithmetic operations, it may be unexpected for the ternary operator.
To avoid confusion or unexpected behavior, cast to a compatible type explicitly.
== How to fix it
=== Code examples
==== Noncompliant code example
Cast one of both operands to a common supertype (e.g., `Number`) to prevent auto-unboxing and, thus, type coercion.
[source,java,diff-id=1,diff-type=noncompliant]
----
Integer i = 123456789;
Float f = 1.0f;
Number n1 = condition ? i : f; // Noncompliant, unexpected precision loss, n1 = 1.23456792E8
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
Integer i = 123456789;
Float f = 1.0f;
Number n1 = condition ? (Number) i : f; // Compliant, cast to Number prevents unboxing
Number n2 = condition ? i : (Number) f; // Compliant, cast to Number prevents unboxing
----
==== Noncompliant code example
If type coercion was your intention, clarify this by casting the operand that would be coerced to the corresponding type explicitly.
[source,java,diff-id=2,diff-type=noncompliant]
----
Integer i = 123456789;
Float f = 1.0f;
Number n1 = condition ? i : f; // Noncompliant, unexpected precision loss, n1 = 1.23456792E8
----
==== Compliant solution
[source,java,diff-id=2,diff-type=compliant]
----
Integer i = 123456789;
Float f = 1.0f;
Number n = condition ? (float) i : f; // Compliant, intentional type coercion with precision loss
----
== Resources
=== Documentation
* https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html[The Java Tutorials: Equality, Relational, and Conditional Operators]
* https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html[The Java Tutorials: Autoboxing and Unboxing]
* https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html[The Java® Language Specification Java SE 7 Edition: Chapter 5. Conversions and Promotions]
=== Articles & blog posts
* https://www.geeksforgeeks.org/coercion-in-java/[GeeksforGeeks: Coercion in Java]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Add an explicit cast to match types of operands.
'''
== Comments And Links
(visible only on this page)
=== on 16 Feb 2015, 18:02:37 Michael Gumowski wrote:
Message changed, as the type of the ternary operation can not be resolved at the moment. Indicating the required cast is not yet possible.
Moreover, other expressions than variables can be used as operand.
endif::env-github,rspecator-view[]