这里有一个通用的方法:
public static <T extends Comparable<T>> T[] function(T[] a)
{
Object[] m = new Object[2];
/* some work here */
return (T[]) m;
}
抛出了一个
ClassCastException
,这是什么问题?这里有一个通用的方法:
public static <T extends Comparable<T>> T[] function(T[] a)
{
Object[] m = new Object[2];
/* some work here */
return (T[]) m;
}
ClassCastException
,这是什么问题?一个Object数组不是任何Object子类的数组。你面临的是Java泛型的限制之一:你不能创建一个泛型数组。参见这个线程中的方法可以解决这个问题。
E[] array = (E[]) new Object[10]; //虽然会产生警告
这与代码中的内容是相同的,不是吗? - Majid Azimi-Xlint:unchecked
编译,你会收到一个警告。除非E
是Object
,否则在运行时你将不会满意结果。 - Ted HoppObject
不是可比较的. 您需要定义您的数组为可比较类型。
由于您正在传递一个数组,因此您可以使用该数组的类型:
T[] m = Array.newInstance(a.getClass().getComponentType(), 2);
当然,您需要将Comparable
对象放入其中。
Array.newInstance
创建新的数组并返回Object[]
,然后我们将其转换为T[]
。这就是我在代码中所做的。 - Majid AzimiE[] e = (E[]) new Object[3]
起作用,但 Object[] o = new Object[3]
然后 E[] e = (E[]) o
不起作用?它们做了相同的事情吗?不是吗? - Majid Azimipublic static Comparable[] function(Comparable[] a)
{
Object[] m = new Object[2];
/* some work here */
return (Comparable[]) m;
}
Object[]
的对象转换为Comparable[]
。就是这样。Comparable[]
而不是Object[]
。public static <T extends Comparable<T>> T[] function(T[] a)
{
Comparable[] m = new Comparable[2];
/* some work here */
return (T[]) m;
}
即使这样,它仍然不会起作用。在此函数内部不会抛出ClassCastException。但是,在调用此函数的任何代码中都会抛出它。例如:
String[] foo = function(new String[0]);
当你擦除类型时,会抛出ClassCastException异常,因为编译器会在泛型方法返回的内容上进行强制类型转换:
String[] foo = (String[])function(new String[0]);
您不能将实际类为Comparable[]
的对象转换为String[]
。
当您询问那些说Array.newInstance()
是在运行时创建一个已知类数组的方法的人“有什么区别”时,区别在于Array.newInstance()
返回的对象的''实际、运行时''类型为Whatever[]
,其中“Whatever”是传递给它的类对象的类。静态值(编译时类型)为Object[]
并不重要;实际运行时类型才是重要的。
当您说“另一个问题是为什么E[] e = (E[]) new Object[3]有效”时,您可能会忽略几个要点。首先,只有在E声明为<E>
或<E extends Object>
时才有效,即E的下限为Object。其次,这基本上是一个谎言(在实现通用集合等多个方面很方便,但您必须理解为什么它很危险);严格来说,当E不是Object时,您''不应该''能够从实际类型为Object[]
的对象转换为E[]
。它之所以“有效”,是因为在E的范围内,E被擦除了,因此我们无法检查转换。但是如果您尝试将该对象作为E[]
返回给外部世界,您将以同样的方式获得ClassCastException。
实际上,你不能将对象数组强制转换为可比较的数组。这是没有意义的。编译器为什么会允许这样做呢?此外,例如,Integer类实现了Comparable接口,但你不能将Comparable数组强制转换为Integer数组。
这是你想要做的事情:
public static <T extends Comparable<T>> T[] function(final T[] a) {
final T[] m = (T[]) Array.newInstance(a.getClass().getComponentType(), 2);
/* some work here */
return m;
}
T extends Comparable 表示方法参数(在本例中为 T)应该从 Comparable 继承。因此,当您尝试进行以下转换时
(T[]) m;
您正在尝试将Object[]强制转换为Comparable[](或任何扩展Comparable的内容)。