
Co-authored-by: Dorian Burihabwa <75226315+dorian-burihabwa-sonarsource@users.noreply.github.com>
87 lines
2.8 KiB
Plaintext
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[]
|