使用类对象创建通用的二维数组

4

我有一个泛型类型,它在构造函数中提供了 Class<T> 对象。我想在这个构造函数中创建二维数组 T[][],不知道是否可能?


请发布您想使用的构造函数的具体签名。这可能是可能的,但不清楚您在问什么。 - chrylis -cautiouslyoptimistic-
1
可以使用Array.newInstance()。请参见https://dev59.com/cXRB5IYBdhLWcg3wvpmc。我会标记为重复,但我没有标记了,有人能处理一下吗? - Jason C
1
@JasonC 这并不完全是一个重复的问题,因为它询问的是关于二维数组的问题,而你链接的那个问题似乎没有讨论创建多维实例的内容,这会导致有人认为它只适用于一维,从而需要比实际上更复杂的过程。 - JAB
@JAB 1) 请看下面我的回答,2) 你会希望(关键词)有人检查Array.newInstance的文档并注意维度参数,3) 至于标记重复...很好的观点,我同意(有点)。 - Jason C
1
它被关闭为重复,尽管我现在基于@JAB上面的评论不同意。此前发布在这里的其他答案(现已删除)表明了对链接问题中描述的1D情况可以扩展到2D的理解不足 - 正是JAB上面描述的情况。我已经在我的回答中尝试展示了这一点。实际上,我认为应该重新打开这个问题,并将另一个问题标记为问题的重复,因为这是一个更普遍的情况。 - Jason C
显示剩余4条评论
2个回答

17

如何在Java中创建通用数组?相同,但对2D进行了扩展:

import java.lang.reflect.Array;

public class Example <T> {

    private final Class<? extends T> cls;

    public Example (Class<? extends T> cls) {
        this.cls = cls;
    }

    public void arrayExample () {
        // a [10][20] array
        @SuppressWarnings("unchecked")
        T[][] array = (T[][])Array.newInstance(cls, 10, 20);
        System.out.println(array.length + " " + array[0].length + " " + array.getClass());
    }

    public static final void main (String[] args) {
        new Example<Integer>(Integer.class).arrayExample();
    }

}

注意阅读JAB上面的评论:要扩展到更多维度,只需向newInstance()添加[]和维数参数(cls是类,d1到d5是整数):
T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

请参阅 Array.newInstance() 以获取详细信息。

我注意到楼主编辑了问题并添加了“在这个构造函数中”。与上面的方法相同(例如,将arrayExample()中的代码移动到构造函数中)。 - Jason C
谢谢,我不知道(我以为我在文档中检查过了)我可以使用带有更多参数的newInstance - 这是我的错,我本可以检查一下的。 - Krzysztof Stanisławek
1
不安全的类型转换为 T[][](或其他)。cls 可能是一个原始类型。 - newacct
@newacct +1 但我已经没有投票了。你需要做一些类似于 new Example<Integer>(int.class) 的操作才能达到那个地步,这可能有点奇怪,但是没错,你是正确的。我有机会会进行更新。 - Jason C
@newacct 没有一个好的方法来处理这种情况。我可以在 arrayExample() 中检查 cls == int.class 并添加一个特殊情况,对于其他原始类型也可以这样做,但是这会导致维护一堆重复代码的噩梦。问题归结为无法将泛型转换为原始类型。因此,虽然如果 cls 是原始类型的类,则示例会失败,但我认为这不值得关注(个人意见)--解决方法是使用对象类型而不是原始类型。 - Jason C
1
@JasonC:嗯,你可以返回Object而不是特定类型的数组。或者至少,多维数组的最后一级必须替换为Object。(因此,二维数组可以安全地表示为Object[];一维数组只能表示为Object。) - newacct

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接