如何从Object []转换为另一种数组类型?

时间:2012-11-28 00:58:38

标签: java classcastexception

我有一个泛型(我不太确定,如果这是正确的术语..)方法,它将一个对象添加到一个数组。

@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;我既没有看到,也没有理解为什么会这样做...我的意思是,我正在使用泛型,那么为什么除了{I}之外还有Object[]在实例化期间转换为T类型?如果它是第4行的那个(当然是代码的第1位),为什么不在那里抛出异常而不是在第2位代码的第3行?

5 个答案:

答案 0 :(得分:3)

不使用System.arraycopy,而是使用Arrays.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;
}

答案 1 :(得分:2)

无法将数组转换为其他数组。

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

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

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

答案 2 :(得分:2)

其他答案已经介绍了如何重写代码以便工作,但问题的后半部分仍然存在,所以:

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

Integer i = (Integer) new Object();

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

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

作为类型擦除过程的一部分,检查您正在声明此方法是否返回Integer[]的声明的代码会在您的方法返回并尝试进行分配时放入。< / p>

答案 3 :(得分: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]

答案 4 :(得分: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;
}