1

就像标题说的那样,我正在尝试以一种通用的方式创建一个多维数组的副本,准确地说是二维数组,这样我就可以在其他地方重用它。

我将传递给它的类型很可能都是用户定义的,例如我有一个我希望以这种方式使用的 Tile 类。

我目前的问题是下面的代码:

在调试器中,您可以跟踪调用并查看数组中的元素是否已正确分配,但一旦返回结果,java 就会抛出此异常:

java.lang.ClassCastException: [[Ljava.lang.Object; 不能转换为 [[Lboard.Tile;

@SuppressWarnings("unchecked")
public static <T> T[][] clone(T[][] source) {
    T[][] result = (T[][]) new Object[source.length][source[0].length];
    for (int row = 0; row < source.length; row++) {
        result[row] = Arrays.copyOf(source[row], source[0].length);
    }
    return result;
}

有人知道这样做的好方法吗?优化不是问题。

谢谢

4

2 回答 2

4

这是我基于 Array.copyOf() 的方法

static <T> T[][] clone(T[][] source) {
    Class<? extends T[][]> type = (Class<? extends T[][]>) source.getClass();
    T[][] copy = (T[][]) Array.newInstance(type.getComponentType(), source.length);

    Class<? extends T[]> itemType = (Class<? extends T[]>) source[0].getClass();
    for (int i = 0; i < source.length; i++) {
        copy[i] = (T[]) Array.newInstance(itemType.getComponentType(), source[i].length);
        System.arraycopy(source[i], 0, copy[i], 0, source[i].length);
    }
    return copy;
}

诀窍是通过显式指定此类型来获取项目的类型并创建数组。

编辑:不要忘记检查源是否为空:)

于 2013-04-06T01:49:42.360 回答
1

发生异常,因为毕竟数组仍然是 typeObject[][]而不是 type T[][]。你可以通过使用反射来解决这个问题,就像这样(但它很讨厌):

T[][] result = (T[][]) java.lang.reflect.Array.newInstance(source[0][0].getClass(), new int[]{source.length, source[0].length});
于 2013-04-06T01:46:13.007 回答