Kevindra Kevindra - 5 months ago 26
Java Question

Findbugs BC_UNCONFIRMED_CAST warning

I have two classes -

class A {}
class B extends A {}


And I was doing this -

A a = new B();
if(a instanceof B){
doSomething((B) a); // type case a to B
}


doSomething method looks like this -

public void doSomething(B b) { .. }


Findbugs raised no warning in above code. But if I change the above code like this -

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 raises an error BC_UNCONFIRMED_CAST. I don't see much difference in both the implementations. Any suggestions, am I missing anything?

Answer Source

FindBugs looks for the instanceof prior to checkcast bytecode. You can use an assert to please the FindBugs warning and future maintainers of your code.

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);
}

Prior to FindBugs 3.0 you could use dynamic cast to work around this warning. Don't do this as it is detected in later versions of FindBugs.

A a = new B();
if (a.isOfTypeB()) {
  doSomething(B.class.cast(a));
}

One of the things to consider is that FindBugs detects patterns that do create actual bugs and patterns that can create actual bugs. The 'instanceof' keyword and Class.cast behavior can’t be overridden but 'isTypeOfB' can be overridden. Even if FindBugs doesn't detect that both examples of your code and mine function as expected, maybe the warning is correct on the grounds that it is advisable to not do this.