0

我有一个通用的(我不太确定这是否是正确的术语..)方法,可以将对象添加到数组中。

@SuppressWarnings("unchecked")
public static <T>T[] appendArray(T[] a, T b)
{
    T[] temp = (T[])new Object[a.length + 1];
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length] = b;
    return temp;
}

在 Eclipse 中,这段代码没有给我任何错误,没有警告(除了被抑制的“未检查”警告),而且在我看来,这应该可以工作。但是,当我尝试使用诸如。 .

Integer[] a=new Integer[]{1,2,3};
Integer b=4;
a = appendArray(a, b);

在这种情况下,它为我提供了ClassCastException我发布的第二段代码的第 3 行。错误说,[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;我既看不到也不明白为什么会这样做。我的意思是,我使用的是泛型,那么为什么除了我在实例化期间强制Object[]键入的那个之外,还有其他的呢?T如果它是第 4 行的那个(当然是在第 1 位代码中),为什么不在那里抛出异常,而不是在第 2 位代码的第 3 行?

4

5 回答 5

3

代替 using System.arraycopy, useArrays.copyOf将数组实例化为泛型类型。

public static <T> T[] appendArray(T[] a, T b) {
    T[] temp = (T[]) Arrays.copyOf(a, a.length + 1, a.getClass());
    temp[a.length] = b;
    return temp;
}
于 2012-11-28T01:05:58.600 回答
2

不能将数组转换为不同的数组。

数组确实有值类型。这[Ljava.lang.Integer;就是说:一个整数数组。这是与对象数组不兼容的类型。

您是否注意到所有的 java 集合类都使用了Object[]?原因是这是他们确信可以存储数据的数组类型。

还要注意该toArray方法的外观。它需要知道您想要退出的数组类型。它无法从泛型中猜出类型;本质上你需要一个原型对象,然后你需要创建一个正确类型的数组。

于 2012-11-28T01:01:07.660 回答
2

其他答案涵盖了如何重写代码以使其工作,但是您问题的后半部分仍然存在,因此:

您似乎从根本上误解了演员表是什么。它不会改变任何东西的真实类型。它告诉编译器“嘿,假装这个 X 类型的引用实际上是一个 Y,相信我,我知道。”

Integer i = (Integer) new Object();

这不会导致 aObject变成Integer! 当 JVM 发现您对编译器撒谎时,它会在运行时引发错误。

错误发生的时间比您在示例中的预期晚的原因是“T”是 java 中的仅编译时概念。出于运行时目的,您可以将每个“T”替换为Object.

作为类型擦除过程的一部分,检查您是否声明此方法返回 an 的代码Integer[]被放入您的方法返回并尝试进行分配的点。

于 2012-11-28T01:14:27.877 回答
1

泛型和数组不能混用!

有办法解决它。您可以使用特殊Array.newInstance()方法创建具有特定组件类型的数组对象:

public static <T> T[] appendArray(T[] a, T b) {
    T[] temp = (T[]) Array.newInstance(b.getClass(), a.length + 1);
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length] = b;
    return temp;
}

此代码在调用时不会引发任何错误:

public static void main(String[] args) {
    Integer[] a = new Integer[] { 1, 2, 3 };
    Integer b = 4;
    a = appendArray(a, b);
    System.out.println(Arrays.toString(a));
}

输出:

[1, 2, 3, 4]
于 2012-11-28T01:03:49.117 回答
0

您可以ArrayList使用泛型创建一个泛型类型T并将其作为数组获取。

@SuppressWarnings("unchecked")
public static <T>T[] appendArray(T[] a, T b)
{
    T[] temp = new ArrayList<T>(Arrays.asList(a)).toArray(a);
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length-1] = b;
    return temp;
}
于 2012-11-28T01:06:34.000 回答