Question

Two classes:

public class ClassA implements ClassC {
    private static final long serialVersionUID = 1111111111111111111L;
    public String varA;
}

public class ClassB extends ClassA implements ClassC {
    private static final long serialVersionUID = 4604935970051141456L;
    public String varB;
}

In my code I have this declaration: ClassB classB;

and a method

myMethod()

that returns a ClassA object.

If I write:

classB = (ClassB) myMethod();

I thought that I will have:

classB.varA = <a value from myMethod()>
classB.varB = null

but this is not so: I receive a ClassCastException.

Why? And how can assign the myMethod() to ClassB in a fast way?

Was it helpful?

Solution

The problem is that you're trying to downcast a ClassA to a ClassB, which isn't allowed because the actual object might be ClassX (another subclass of ClassA) which doesn't have an explicit conversion.

See the following example which will throw a ClassCastException (but compiles just fine):

public class Main {
    public static void main(String[] args) {
        SubB var = (SubB) someMethod();         
    }

    private static Super someMethod(){
        return new SubA();
    }
}

class Super { }
class SubA extends Super { }
class SubB extends Super { }

The code compiles perfectly:

  • someMethod() returns a class of type Super.
  • SubA extends Super so the method definition isn't violated
  • SubB extends Super so it can cast an object of type Super to SubB

Yet when you execute this, you'll try to cast an object of type SubA to SubB, which isn't possible.

Sidenotes:

  • Don't use ClassC to name an interface
  • Put hierarchy in your classnames for small examples here (Super <-> Sub) instead of (A <-> B <-> C)

OTHER TIPS

Casts in Java are not like dynamic_cast<...> of pointers in C++. With the latter, if the types are incompatible, the result is a null pointer. In Java, casting incompatible references results in ClassCastException.

The usual Java idiom is to test the reference beforehand using instanceof and then only performing the cast if the result is true. For example,

ClassA a = myMethod();
if (a instanceof ClassB) {
    ClassB b = (ClassB) a;
    ...
}

ClassA are not ClassB interchangable. Change your method to return ClassC (the interface), and store that reference as a ClassC and then you can use ClassA or ClassB. A is-a C and B is-a C, but A is-not a B even though B is-a A. If that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top