多态性困惑:如何从 `Constructor.getInstance()` 访问正确的 class?

Polymorphism confusion: How to access the correct class from `Constructor.getInstance()`?

我有一个基地class,叫做BaseMatrix,还有几个children。我有 pre-created 个这些 children 的实例来做一些单元测试并将它们放在列表中 toUnitTest.

但是,我也想测试我所有的构造函数,所以我想利用我的 pre-created 实例使用 m.getClass() 来创建一个新的 object类型但具有不同的构造函数。例如,一个这样的构造函数采用 double[][]。发现是Constructor.newInstance()returnsObject,于是尝试投射:

    // 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();
            }
        }
    }

这导致非法参数异常:

java.lang.IllegalArgumentException: wrong number of arguments

Based on this answer,我想我正在将我的 child 转换回 parent class,它没有这个只需要 [=17 的构造函数=].所有 child classes 都有接受这个参数的构造函数,所以我想我只需要弄清楚如何正确转换。我该怎么做?

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.newInstanceObject[] 作为其参数,它使用可变参数。代码传递了一个 double[][],它是 Object[] 的一个实例,因为引用数组在 Java.

中的工作方式很奇怪

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

一个简单的解决方法是显式创建数组,就像该方法没有使用可变参数一样。

c.newInstance(new Object[] { testArr })

另一个值得注意的问题是 c 被声明为原始类型 Constructor。这应该给出警告(注意警告!)。所以

            Constructor<? extends BaseMatrix> c = // ...