Modify rule S4348: reworked rule description for LaYC format (#2873)
This commit is contained in:
parent
76c34b093a
commit
74437e0a15
@ -1,16 +1,27 @@
|
||||
== Why is this an issue?
|
||||
|
||||
There are two classes in the Java standard library that deal with iterations: ``++Iterable<T>++`` and ``++Iterator<T>++``. An ``++Iterable<T>++`` represents a data structure that can be the target of the "for-each loop" statement, and an ``++Iterator<T>++`` represents the state of an ongoing traversal. An ``++Iterable<T>++`` is generally expected to support multiple traversals.
|
||||
An `Iterable` should not implement the `Iterator` interface or return `this` as an `Iterator`.
|
||||
The reason is that `Iterator` represents the iteration process itself, while `Iterable` represents the object we want to iterate over.
|
||||
|
||||
An ``++Iterator<T>++`` that also implements ``++Iterable<t>++`` by returning itself as its ``++iterator()++`` will not support multiple traversals since its state will be carried over.
|
||||
The `Iterator` instance encapsulates state information of the iteration process, such as the current and next element.
|
||||
Consequently, distinct iterations require distinct `Iterator` instances, for which `Iterable` provides the factory method `Iterable.iterator()`.
|
||||
|
||||
This rule raises an issue when the `Iterable.iterator()` of a class implementing both `Iterable` and `Iterator` returns `this`.
|
||||
|
||||
This rule raises an issue when the ``++iterator()++`` method of a class implementing both ``++Iterable<T>++`` and ``++Iterator<t>++`` returns ``++this++``.
|
||||
=== What is the potential impact?
|
||||
|
||||
The `Iterable.iterator()` method returning the same `Iterator` instance many times would have the following effects:
|
||||
|
||||
=== Noncompliant code example
|
||||
1. For subsequent iterations, e.g., two subsequent `for` loops with iterators over the same object, only the first one would iterate, and the others would do nothing.
|
||||
2. For nested iterations over the same object, the different iteration processes would affect each other because they only have a common, shared state.
|
||||
|
||||
[source,java]
|
||||
== How to fix it
|
||||
|
||||
=== Code examples
|
||||
|
||||
==== Noncompliant code example
|
||||
|
||||
[source,java,diff-id=1,diff-type=noncompliant]
|
||||
----
|
||||
class FooIterator implements Iterator<Foo>, Iterable<Foo> {
|
||||
private Foo[] seq;
|
||||
@ -31,16 +42,15 @@ class FooIterator implements Iterator<Foo>, Iterable<Foo> {
|
||||
}
|
||||
----
|
||||
|
||||
==== Compliant solution
|
||||
|
||||
=== Compliant solution
|
||||
|
||||
[source,java]
|
||||
[source,java,diff-id=1,diff-type=compliant]
|
||||
----
|
||||
class FooSequence implements Iterable<Foo> {
|
||||
private Foo[] seq;
|
||||
|
||||
public Iterator<Foo> iterator() {
|
||||
return new Iterator<Foo>() {
|
||||
return new Iterator<Foo>() { // Compliant
|
||||
private int idx = 0;
|
||||
|
||||
public boolean hasNext() {
|
||||
@ -56,6 +66,14 @@ class FooSequence implements Iterable<Foo> {
|
||||
}
|
||||
----
|
||||
|
||||
== Resources
|
||||
|
||||
=== Documentation
|
||||
|
||||
* https://docs.oracle.com/javase/7/docs/api/java/lang/Iterable.html[Java SE 7 API Specification: java.lang.Iterable]
|
||||
* https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html[Java SE 7 API Specification: java.util.Iterator]
|
||||
* https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2[Java 7 Language Specification: The enhanced for statement] (since Java 1.5)
|
||||
|
||||
ifdef::env-github,rspecator-view[]
|
||||
|
||||
'''
|
||||
|
Loading…
x
Reference in New Issue
Block a user