2014-03-28 56 views
3

我有两个类 -FindBugs的BC_UNCONFIRMED_CAST警告

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

如果(a.isOfTypeB())或doSomething((B)a))在行上引发错误? – algorithmic

+0

它是在doSomething((B)a)行上提出的。更新了问题 – Kevindra

+0

findbug可能无法确定方法调用isOfTypeB是否为检查实例。 – algorithmic

回答

6

FindBugs在checkcast字节码之前寻找instanceof。您可以使用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的检测模式,创建实际的错误和模式可以创建实际的错误。 'instanceof'关键字和Class.cast行为不能被覆盖,但'isTypeOfB'可以被覆盖。即使FindBugs没有检测到您的代码和我的预期功能的例子,也许警告是正确的,理由是不建议这样做。

1

对于那些希望将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); 
    } 

BC_UNCONFIRMED_CAST错误不会在findbugs报告中报告。

相关问题