hasNext 实现中的 next¶
ID: java/iterator-hasnext-calls-next
Kind: problem
Security severity:
Severity: warning
Precision: medium
Tags:
- reliability
- correctness
Query suites:
- java-security-and-quality.qls
具有调用 next
方法的 hasNext
方法的迭代器实现很可能是错误的。这是因为 next
会将迭代器的位置更改为下一个元素并返回该元素,这在 hasNext
的实现中不太可能需要。
建议¶
确保从 hasNext
中对 next
的任何调用都是合法的。 hasNext
方法应指示迭代中是否还有其他元素,而无需通过调用 next
来更改迭代器状态。
示例¶
在以下示例中,输出字符串的内容,hasNext
调用 next
,这会更改迭代器的位置。鉴于 main
在输出项目时也会调用 next
,因此会跳过一些项目,并且只输出一半的项目。
public class NextFromIterator implements Iterator<String> {
private int position = -1;
private List<String> list = new ArrayList<String>() {{
add("alpha"); add("bravo"); add("charlie"); add("delta"); add("echo"); add("foxtrot");
}};
public boolean hasNext() {
return next() != null; // BAD: Call to 'next'
}
public String next() {
position++;
return position < list.size() ? list.get(position) : null;
}
public void remove() {
// ...
}
public static void main(String[] args) {
NextFromIterator x = new NextFromIterator();
while(x.hasNext()) {
System.out.println(x.next());
}
}
}
相反,hasNext
的实现应使用另一种方法来指示字符串中是否有其他元素,而无需调用 next
。例如,hasNext
可以直接检查底层数组,以查看下一个位置是否有元素。
参考¶
Java API 规范:Iterator.hasNext(),Iterator.next()。