Java 多态性混淆:如何从`Constructor.getInstance()`访问正确的类?

Java 多态性混淆:如何从`Constructor.getInstance()`访问正确的类?,java,inheritance,reflection,casting,variadic-functions,Java,Inheritance,Reflection,Casting,Variadic Functions,我有一个名为BaseMatrix的基类,以及其中的几个子类。我已经预先创建了这些子项的实例,以便对它们进行一些单元测试,并将它们放入列表toUnitTest 但是,我还想测试我的所有构造函数,所以我想利用我使用m.getClass()预先创建的实例来创建一个相同类型但具有不同构造函数的新对象。例如,一个这样的构造函数接受一个double[][]。我发现Constructor.newInstance()返回Object,所以我尝试强制转换它: // This is in the unit

我有一个名为
BaseMatrix
的基类,以及其中的几个子类。我已经预先创建了这些子项的实例,以便对它们进行一些单元测试,并将它们放入列表
toUnitTest

但是,我还想测试我的所有构造函数,所以我想利用我使用
m.getClass()
预先创建的实例来创建一个相同类型但具有不同构造函数的新对象。例如,一个这样的构造函数接受一个
double[][]
。我发现
Constructor.newInstance()
返回
Object
,所以我尝试强制转换它:

    // This is in the unit test class.
    
    private static double[][] testArr = new double[][]{{0, 0}, {0, 0}};
    private static ArrayList<BaseMatrix> toUnitTest = new ArrayList<>();

    @BeforeAll
    public static void startUp() {
        toUnitTest.add(new ND4JDenseMatrix(testRows, testCols));
        toSpeedTest.add(new JamaDenseMatrix(testRows, testCols));
        toSpeedTest.add(new EjmlDenseMatrix(testRows, testCols));
        toSpeedTest.add(new ColtDenseMatrix(testRows, testCols));
    }

    @Test
    void createFromArray(){
        for (BaseMatrix m : toUnitTest) {
            try {
                Constructor c = m.getClass().getDeclaredConstructor(double[][].class);
                BaseMatrix M = m.getClass().cast(c.newInstance(testArr));
                // ... some assertions to check the data ...
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
,我想我正在将我的孩子转换回父类,父类没有这个构造函数,它只接受一个
double[][]
。所有的子类都有接受这个参数的构造函数,所以我想我只需要弄清楚如何正确地强制转换。我该怎么做

private static double[][] testArr = new double[][]{{0, 0}, {0, 0}};
// ,,,
            Constructor c = m.getClass().getDeclaredConstructor(double[][].class);
            BaseMatrix M = m.getClass().cast(c.newInstance(testArr));
Constructor.newInstance
Object[]
作为其参数,该参数使用varargs。代码传递一个
double[][]
,这是
Object[]
的一个实例,因为引用数组在Java中的工作方式很奇怪

在J2SE 5.0之前,诸如
newInstance
之类的方法不能变元,因此为了向后兼容,可分配给适当数组的任何单个参数都将
解释为
[]

一个简单的修复方法是显式地创建数组,就好像该方法没有使用varargs一样

c.newInstance(new Object[] { testArr })
另一个值得注意的问题是
c
被声明为原始类型
构造函数
。这应该会发出警告(注意警告!)。所以


构造函数有一件事我不清楚。。你为什么要选演员?为什么不简单地将新实例添加到列表中呢?如果我不清楚,很抱歉。我已经有了一个用于其他测试目的的对象列表(即mathy stuff)。现在,我需要测试所有的构造函数是否都在工作。因此,由于我有一组实例,我可以使用它们来获取其他唯一的构造函数,并在for循环中测试它们。在构造函数被证明有效后,我不需要这些实例,所以我不想将这些对象添加到我的测试数组中。为什么不存储类而不是实例?为什么创建一个实例只是为了执行getClass()?我不会诚实地设计我的测试,而是有一个专门的测试类,每个构造函数都有一个测试。我看到您正试图避免为此浪费代码,但您试图做的是危险的。这在技术上是可行的,但它可能会隐藏一些东西(例如,如果有人扩展了你的基类并在构建过程中创建了一些复杂的逻辑,你怎么知道要测试什么,实例的创建是否在功能上起作用呢?)你能为BaseMatrix发布代码吗?至少是构造器。我同意@MatteoNNZ,测试应该明确地测试每个实现。这确实有效。其中一条评论表明,也许我做事的方式不是最佳实践。“你同意吗?”我会完全避免思考。工厂会更好。更短:
c.newInstance((Object)testArr)
c.newInstance(new Object[] { testArr })
            Constructor<? extends BaseMatrix> c = // ...