java升级打破了单元测试

时间:2016-07-26 20:00:56

标签: java junit upgrade

在我的工作环境中,我们被迫从Java 1.6升级到Java 1.8。我们确实修复了此升级中引入的大部分代码破坏,但我们现在偶然发现了以下内容:

在Java 1.6中正确执行:

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

class TestChart extends TestViz
{
}

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

现在chart.duplicate()会返回TestFrame,因此会播放。

不幸的是,使用Java 1.8时,此代码失败,使用java.lang.ClassCastException

有人知道关于抽象类转换的变化,以及可能如何修复此代码?

谢谢。

修改

错误消息显示:

"TestFrame cannot be cast to TestChart"

1 个答案:

答案 0 :(得分:2)

发生错误是因为您尝试执行无效的转换操作。

您的TestChart类是TestFrame的子类。这意味着以下演员表有效:

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

这是因为Java将处理您的chart对象,就好像它是TestFrame(它是!),因此TestChart的任何特定变量或方法都不会在这里显示(因为它们不属于TestFrame)。

然而,当你试图向相反的方向前进时,做一个类似

的演员表
TestFrame frame = new TestFrame();
TestChart chart = (TestChart) frame;

您将获得ClassCastException,因为您无法以这种特定方式处理TestFrame课程。在TestChart(甚至TestViz)中声明的方法和变量不会出现在frame对象中(因为,猜猜是......它是TestFrame },而不是TestChart!)

这是继承在Java中的工作方式。您可以通过其超级类之一广泛地引用对象,但您可以从不通过其 sub 类之一引用对象因为你会试图缩小范围而不是语言可以支持你。

如果考虑到duplicate()返回的对象属于TestFrame类型,您可以进行测试,那么您的代码就像

TestFrame chartClone = chart.duplicate();

这应该可以正常工作。另一个解决方案是更改duplicate()方法的签名并返回TestChart类型的对象,因此不需要强制转换。