rspec/rules/S4838/java/rule.adoc

96 lines
2.4 KiB
Plaintext
Raw Normal View History

== Why is this an issue?
When iterating over an `Iterable` with a `for` loop, the iteration variable could have the same type as the type returned by the iterator (the item type of the `Iterable`).
This rule reports when a supertype of the item type is used for the variable instead, but the variable is then explicitly downcast in the loop body.
2021-04-28 16:49:39 +02:00
Using explicit type casts instead of leveraging the language's type system is a bad practice.
It disables static type checking by the compiler for the cast expressions, but potential errors will throw a `ClassCastException` during runtime instead.
2021-04-28 16:49:39 +02:00
== How to fix it
2021-04-28 16:49:39 +02:00
=== Code examples
==== Noncompliant code example
2021-04-28 16:49:39 +02:00
When declaring the iteration variable, use the item type for it instead of a supertype.
Remove the explicit downcasts in the loop body.
2021-04-28 16:49:39 +02:00
[source,java,diff-id=1,diff-type=noncompliant]
----
for (Object item : getPersons()) { // Noncompliant, iteration element is implicitly upcast here
Person person = (Person) item; // Noncompliant, item is explicitly downcast here
2023-08-18 15:55:15 +02:00
person.getAddress();
2021-04-28 16:49:39 +02:00
}
----
==== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
2021-04-28 16:49:39 +02:00
----
for (Person person : getPersons()) { // Compliant
2023-08-18 15:55:15 +02:00
person.getAddress();
2021-04-28 16:49:39 +02:00
}
----
==== Noncompliant code example
Alternatively, use the `var` keyword to automatically infer the variable type (since Java 10).
[source,java,diff-id=2,diff-type=noncompliant]
----
for (Object item : getPersons()) { // Noncompliant, iteration element is implicitly upcast here
Person person = (Person) item; // Noncompliant, item is explicitly downcast here
2023-08-18 15:55:15 +02:00
person.getAddress();
}
----
==== Compliant solution
[source,java,diff-id=2,diff-type=compliant]
----
for (var person : getPersons()) { // Compliant
2023-08-18 15:55:15 +02:00
person.getAddress();
}
----
==== Compliant solution
The implicit upcast in the loop header is not reported when there is no downcast in the loop body.
2023-08-18 15:55:15 +02:00
[source,java]
----
for (Object item : getPersons()) { // Compliant
System.out.println(item);
}
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Change "XXX" by the type handled by the Collection.
=== Highlighting
First: the "wrong" type
Second: the Collection part of the iteration
'''
== Comments And Links
(visible only on this page)
=== on 12 Sep 2018, 16:41:38 Alexandre Gigleux wrote:
\[~nicolas.peru] Can you review?
=== on 12 Sep 2018, 16:45:47 Nicolas Peru wrote:
LGTM
endif::env-github,rspecator-view[]