Findbugs BC_UNCONFIRMED_CAST警告

Kev*_*dra 5 java findbugs

我有两节课 -

class A {}
class B extends A {}
Run Code Online (Sandbox Code Playgroud)

而我这样做 -

A a = new B();
if(a instanceof B){
   doSomething((B) a); // type case a to B
}
Run Code Online (Sandbox Code Playgroud)

doSomething方法看起来像这样 -

public void doSomething(B b) { .. }
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

Findbugs引发错误BC_UNCONFIRMED_CAST.我认为两种实现都没有太大区别.有什么建议吗,我错过了什么吗?

jme*_*ens 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);
}
Run Code Online (Sandbox Code Playgroud)

在FindBugs 3.0之前,您可以使用动态强制转换来解决此警告.不要这样做,因为在FindBugs的更高版本中检测到它.

A a = new B();
if (a.isOfTypeB()) {
  doSomething(B.class.cast(a));
}
Run Code Online (Sandbox Code Playgroud)

需要考虑的一件事是,FindBugs检测到的模式确实会产生可能产生实际错误的实际错误和模式.无法覆盖'instanceof'关键字和Class.cast行为,但可以覆盖'isTypeOfB'.即使FindBugs没有检测到您的代码和我的两个示例都按预期运行,也许警告是正确的,理由是不建议这样做.