我有一个泛型(我不太确定,如果这是正确的术语..)方法,它将一个对象添加到一个数组。
@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行?
答案 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;
}