CodeQL 文档

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

点击查看 CodeQL 存储库中的查询

具有调用 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 可以直接检查底层数组,以查看下一个位置是否有元素。

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私