Igor
Igor

Reputation: 6275

java upgrade broke the unit test

We were forced to go from Java 1.6 up to Java 1.8 in my work environment. We did fix most of the code breakage which were introduced in this upgrade, but we now stumbled across following:

In Java 1.6 following were executing correctly:

class TestViz extends TestFrame
{
// this class is abstract
}

class TestChart extends TestViz
{
}

class MyClassTest extends JUnit
{
    public MyTest()
    {
        TestChart chartClone = (TestChart) chart.duplicate();
    }
}

Now the chart.duplicate() returns TestFrame, hence the cast.

Unfortunately using Java 1.8 this code fails, with the java.lang.ClassCastException.

Does anybody know what changed in regards to abstract class casting and probably how to fix this code?

Thank you.

EDIT

The error message says:

"TestFrame cannot be cast to TestChart"

Upvotes: 0

Views: 291

Answers (1)

Bruno Toffolo
Bruno Toffolo

Reputation: 1554

The error happens because you trying to perform an invalid casting operation.

Your TestChart class is a subclass of TestFrame. This means that the following cast is valid:

TestChart chart = new TestChart();
TestFrame frame = (TestFrame) chart;

This is because Java will handle your chart object as if it was a TestFrame (which it is!), so any specific variables or method of TestChart will not be visible here (as they are not part of TestFrame).

However, when you try to go in the opposite direction, making a cast like

TestFrame frame = new TestFrame();
TestChart chart = (TestChart) frame;

You will get a ClassCastException, because you can not handle the TestFrame class in such a specific way. There are methods and variables declared in TestChart (and even in TestViz) that will not be present in your frame object (because, guess what... it is a TestFrame, and not a TestChart!)

This is how inheritance work in Java. You can always broadly refer to an object by one of its superclasses, but you can never refer to an object by one of its subclasses because you would be trying to narrow things more than the language can support you on.


If you can do your test considering that the object returned by duplicate() is of type TestFrame, your code would be like

TestFrame chartClone = chart.duplicate();

and that should work fine. Another solution would be changing the duplicate() method's signature and return an object of type TestChart, so no cast would be needed.

Upvotes: 2

Related Questions