Reputation: 6275
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
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