我有两个班级 -
class A {}
class B extends A {}
我这样做 -
A a = new B();
if(a instanceof B){
doSomething((B) a); // type case a to B
}
doSomething方法看起来像这样 -
public void doSomething(B b) { .. }
Findbugs在上面的代码中没有引发任何警告。但如果我改变上面的代码 -
class A {
public boolean isOfTypeB() {
return this instanceof B;
}
}
class B extends A {}
A a = new B();
if(a.isOfTypeB()){
doSomething((B) a); // BC_UNCONFIRMED_CAST warning
}
Findbugs引发错误BC_UNCONFIRMED_CAST。我认为两种实现都没有太大区别。有什么建议吗,我错过了什么吗?
答案 0 :(得分:9)
FindBugs在instanceof
字节码之前查找checkcast
。您可以使用assert
取代FindBugs警告以及代码的未来维护者。
A a = new B();
if (a.isOfTypeB()){
assert a instanceof B : a.getClass(); //Safe to call getClass because 'a' is non-null.
doSomething((B) a);
}
在FindBugs 3.0之前,您可以使用动态强制转换来解决此警告。不要在FindBugs的更高版本中检测到这一点。
A a = new B();
if (a.isOfTypeB()) {
doSomething(B.class.cast(a));
}
击> <击> 撞击>
需要考虑的事情之一是,FindBugs会检测执行创建可以创建实际错误的实际错误和模式的模式。 &#39;实例&#39;关键字和Class.cast行为不能被覆盖,但是&#39; isTypeOfB&#39;可以被覆盖。即使FindBugs没有检测到您的代码和我的两个示例都按预期运行,也许警告是正确的,理由是不建议这样做。
答案 1 :(得分:2)
对于那些希望将ServletResponse转换为HttpServletResponse的人,请使用 instanceof ,如下所示。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (response instanceof HttpServletResponse)
noCaching((HttpServletResponse) response);
chain.doFilter(request, response);
}
在findbugs报告中不会报告BC_UNCONFIRMED_CAST错误。