rspec/rules/S1849/java/rule.adoc

84 lines
2.0 KiB
Plaintext

== Why is this an issue?
Calling `Iterator.hasNext()` is not supposed to have any side effects and hence should not change the iterator's state. `Iterator.next()` advances the iterator by one item. So calling it inside `Iterator.hasNext()` breaks the `hasNext()` contract and will lead to unexpected behavior in production.
== How to fix it
How to fix this issue strongly depends on the specific implementation of the iterator. Make sure that the logic of the `hasNext()` implementation does not change the state of the iterator or any underlying data sources. Instead, it should merely return state information.
== Code examples
=== Noncompliant code example
[source,java,diff-id=1,diff-type=noncompliant]
----
class MyIterator implements Iterator<Integer> {
private Queue<Integer> elements;
...
@Override
public boolean hasNext() {
try {
next(); // Noncompliant, next() is called from hasNext()
return true;
} catch (NoSuchElementException e) {
return false;
}
}
@Override
public Integer next() {
return elements.remove();
}
}
----
=== Compliant solution
[source,java,diff-id=1,diff-type=compliant]
----
class MyIterator implements Iterator<Integer> {
private Queue<Integer> elements;
...
@Override
public boolean hasNext() {
return !elements.isEmpty(); // Compliant, no call to next()
}
@Override
public Integer next() {
return elements.remove();
}
}
----
== Resources
* https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Iterator.html[Interface Iterator<E> - Java® Platform SE 11 API Specification]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Refactor the implementation of this "Iterator.hasNext()" method to not call "Iterator.next()".
'''
== Comments And Links
(visible only on this page)
=== on 21 Nov 2024, 16:48:00 Alban Auzeill wrote:
[test-code-support-investigation-for-java] Decision for scope: Main -> All.
=== is duplicated by: S2113
endif::env-github,rspecator-view[]