Maj*_*imi 5 java generics static-methods
这里我们有通用方法:
public static <T extends Comparable<T>> T[] function(T[] a)
{
Object[] m = new Object[2];
/* some work here */
return (T[]) m;
}
Run Code Online (Sandbox Code Playgroud)
AClassCastException被抛出。它出什么问题了?
你在这里有两个不同的问题。
首先,删除泛型并查看没有泛型的代码(这是在编译时删除的内容):
public static Comparable[] function(Comparable[] a)
{
Object[] m = new Object[2];
/* some work here */
return (Comparable[]) m;
}
Run Code Online (Sandbox Code Playgroud)
您无法将其实际运行时类转换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;
}
Run Code Online (Sandbox Code Playgroud)
它仍然不起作用。它不会在此函数内抛出 ClassCastException。但它会把它扔到任何调用这个函数的代码中。例如,
String[] foo = function(new String[0]);
Run Code Online (Sandbox Code Playgroud)
会抛出 ClassCastException,因为当你删除它时,你会看到编译器为泛型方法产生的内容进行了强制转换:
String[] foo = (String[])function(new String[0]);
Run Code Online (Sandbox Code Playgroud)
并且您不能强制转换实际类为Comparable[]to的对象String[]。
当您向人们询问“有什么区别”时,他们说这Array.newInstance()是创建运行时已知的类的数组的方法。区别在于,返回的对象Array.newInstance()具有“实际的运行时”类型Whatever[],其中“Whatever”是传递给它的类对象的类。静态(值的编译时类型)类型是 并不重要Object[];重要的是实际的运行时类型。
当你说“另一个问题是为什么 E[] e = (E[]) new Object[3] 有效”时,你可能在这里遗漏了几点。首先,只有当 E 被声明为<E>or时才有效<E extends Object>,即 E 的下界是 Object。其次,这基本上是一个谎言(这在很多地方都很方便,比如实现通用集合;但你必须理解为什么它是危险的);从形式上来说,当 E 不是 Object 时,您“不应该”能够从实际类型为Object[]to的对象进行强制转换。E[]它之所以“有效”,是因为在 E 的范围内,E 被擦除,因此我们无法检查强制转换。但是,如果您尝试将该对象作为 an 返回E[]给外界,您将以同样的方式得到 ClassCastException。