Equals 方法不检查参数类型¶
ID: java/unchecked-cast-in-equals
Kind: problem
Security severity:
Severity: error
Precision: high
Tags:
- reliability
- correctness
Query suites:
- java-security-and-quality.qls
为了避免失败的转换,equals
的实现必须能够处理任何类型的参数。因此,实现应检查其参数的类型,以查看参数是否可以安全地转换为声明 equals
方法的类。
建议¶
通常,equals
的实现应使用 instanceof
检查其参数的类型,遵循以下一般模式。
class A {
// ...
public final boolean equals(Object obj) {
if (!(obj instanceof A)) {
return false;
}
A a = (A)obj;
// ...further checks...
}
// ...
}
以这种方式使用 instanceof
的好处在于,它包括防止空指针异常的保护:如果 obj
为 null
,则检查失败并返回 false
。因此,在检查之后,可以保证 obj
不为 null
,并且可以安全地访问其字段。
每当使用 instanceof
检查参数类型时,应将 equals
方法声明为 final
,这样子类将无法通过进一步覆盖 equals
来导致违反 equals
契约的对称性要求。
如果您希望子类通过覆盖 equals
来重新定义相等性的概念,请使用 getClass
而不是 instanceof
来检查参数类型。但是,请注意,使用 getClass
会阻止类实例与其子类之间的任何相等性关系,即使子类中没有添加任何其他状态也是如此。
参考¶
J. Bloch,Effective Java(第二版),第 8 项。Addison-Wesley,2008 年。
Java API 规范:Object.equals()。
Java 语言规范:类型比较运算符 instanceof。