Findbugs BC_UNCONFIRMED_CAST警告

时间:2014-03-28 20:09:07

标签: java findbugs

我有两个班级 -

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。我认为两种实现都没有太大区别。有什么建议吗,我错过了什么吗?

2 个答案:

答案 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错误。