CodeQL 文档

调用 Iterator.remove 可能会失败

ID: java/iterator-remove-failure
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - reliability
   - correctness
   - logic
Query suites:
   - java-security-and-quality.qls

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

Iterator 接口的 remove 方法是一个可选操作。不可修改集合的迭代器或由 Arrays.asList 方法构造的列表的迭代器不支持该方法。在这种迭代器上调用 remove 将导致 UnsupportedOperationException

建议

如果要在构造后修改集合,请使用可修改的集合类型,例如 ArrayListHashSet

示例

在以下示例中,构造函数 A(Integer...) 将字段 A.l 初始化为 Arrays.asList(is)。虽然 Arrays.asList 返回的列表类型支持通过 set 方法更新元素,但它不支持删除元素。因此,在第 20 行调用 iter.remove 在运行时一定会失败。

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class A {
	private List<Integer> l;
	
	public A(Integer... is) {
		this.l = Arrays.asList(is);
	}
	
	public List<Integer> getList() {
		return l;
	}

	public static void main(String[] args) {
		A a = new A(23, 42);
		for (Iterator<Integer> iter = a.getList().iterator(); iter.hasNext();)
			if (iter.next()%2 != 0)
				iter.remove();
	}
}

为了避免这种失败,请将 Arrays.asList 返回的列表复制到新创建的 ArrayList 中,如下所示

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

public class A {
	private List<Integer> l;
	
	public A(Integer... is) {
		this.l = new ArrayList<Integer>(Arrays.asList(is));
	}
	
	public List<Integer> getList() {
		return l;
	}

	public static void main(String[] args) {
		A a = new A(23, 42);
		for (Iterator<Integer> iter = a.getList().iterator(); iter.hasNext();)
			if (iter.next()%2 != 0)
				iter.remove();
	}
}

参考资料

  • ©2025GitHub 公司
  • 条款
  • 隐私