容器修改类型不匹配¶
ID: java/type-mismatch-modification
Kind: problem
Security severity:
Severity: error
Precision: very-high
Tags:
- reliability
- correctness
- logic
Query suites:
- java-security-and-quality.qls
Collection
接口的 remove
方法有一个类型为 Object
的参数。因此,您可以尝试从集合中删除任何类型的对象,而不管集合的元素类型。但是,尽管您可以使用与集合不同的类型的参数调用 remove
,但该集合不太可能实际包含这种类型的对象。
类似的考虑适用于其他容器修改方法,例如 Map.remove
,其中参数也可能具有类型 Object
。
建议¶
确保您在调用 remove
时使用正确的参数。
示例¶
在以下示例中,虽然 contains
的参数是整数,但代码不会导致类型错误,因为 remove
的参数不必与 list
元素的类型匹配。但是,该参数不太可能被找到并删除(因此 if
语句的主体不会执行),所以它可能是一个拼写错误:该参数应该用引号括起来。
void m(List<String> list) {
if (list.remove(123)) { // Call 'remove' with non-string argument (without quotation marks)
// ...
}
}
请注意,在处理装箱类型集合时,您必须格外小心,如下面的示例所示。第一次调用 remove
失败,因为您不能比较两个不同类型的装箱数值基本类型,在本例中是 Short(1)
(在 set
中)和 Integer(1)
(参数)。因此,remove
无法找到要删除的项。第二次调用 remove
成功,因为您可以比较 Short(1)
和 Short(1)
。因此,remove
可以找到要删除的项。
HashSet<Short> set = new HashSet<Short>();
short s = 1;
set.add(s);
// Following statement fails, because the argument is a literal int, which is auto-boxed
// to an Integer
set.remove(1);
System.out.println(set); // Prints [1]
// Following statement succeeds, because the argument is a literal int that is cast to a short,
// which is auto-boxed to a Short
set.remove((short)1);
System.out.println(set); // Prints []
参考文献¶
Java API 规范:Collection.remove.