2023-05-03 11:06:20 +02:00
== Why is this an issue?
2023-08-16 10:26:18 +02:00
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
2023-08-16 10:26:18 +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
2023-08-16 10:26:18 +02:00
== How to fix it
2021-04-28 16:49:39 +02:00
2023-08-16 10:26:18 +02:00
=== Code examples
2021-04-28 18:08:03 +02:00
2023-08-16 10:26:18 +02:00
==== Noncompliant code example
2021-04-28 16:49:39 +02:00
2023-08-16 10:26:18 +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
2023-08-16 10:26:18 +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
}
----
2023-08-16 10:26:18 +02:00
==== Compliant solution
2021-04-28 18:08:03 +02:00
2023-08-16 10:26:18 +02:00
[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
}
----
2021-04-28 18:08:03 +02:00
2023-08-16 10:26:18 +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();
2023-08-16 10:26:18 +02:00
}
----
==== 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();
2023-08-16 10:26:18 +02:00
}
----
==== 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]
2023-08-16 10:26:18 +02:00
----
for (Object item : getPersons()) { // Compliant
System.out.println(item);
}
----
2021-06-02 20:44:38 +02:00
2021-06-03 09:05:38 +02:00
ifdef::env-github,rspecator-view[]
2021-09-20 15:38:42 +02:00
'''
== Implementation Specification
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== Message
Change "XXX" by the type handled by the Collection.
=== Highlighting
First: the "wrong" type
Second: the Collection part of the iteration
2021-09-20 15:38:42 +02:00
2021-06-08 15:52:13 +02:00
'''
2021-06-02 20:44:38 +02:00
== Comments And Links
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== 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
2021-06-03 09:05:38 +02:00
endif::env-github,rspecator-view[]