Cay Horstmann的Java泛型,核心Java 7,第一卷,第716页

Cay Horstmann的Java泛型,核心Java 7,第一卷,第716页,java,generics,Java,Generics,我正在学习Java7泛型,阅读CayHorstmann,CoreJava7,第一卷,第716页。 我不明白为什么会发生运行时错误(强制转换非法),请参阅下面的代码。 有谁能比凯伊更好地解释给我听吗 public class ProcessArgs { public static <T extends Comparable> T[] minmax(T... a) { Object[] mm = new Object[2]; mm[0] = a[0];

我正在学习Java7泛型,阅读CayHorstmann,CoreJava7,第一卷,第716页。 我不明白为什么会发生运行时错误(强制转换非法),请参阅下面的代码。 有谁能比凯伊更好地解释给我听吗

public class ProcessArgs 
{

  public static <T extends Comparable> T[] minmax(T... a)
  {
    Object[] mm = new Object[2];
    mm[0] = a[0];
    mm[1] = a[1];
    if (mm[0] instanceof Comparable)
    {
        System.out.println("Comparable"); // this is True, prints Comparable at run-time
    }
    return (T[]) mm;  // run-time error here

    /* Run-Time ERROR as below:
     ComparableException in thread "main" 
     java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
      at ProcessArgs.minmax(ProcessArgs.java:13)
      at ProcessArgs.main(ProcessArgs.java:18)
     */

  }

  public static void main(String[] args) 
  {
    String[] sa = minmax("Hello","World"); // ERROR, illegal cast
    System.out.println(sa[0] + sa[1]);
    Object o = "Hello World"; //works - if we comment out the method call to minmax above
    Comparable<String> s = (Comparable) o; // works
    Comparable s2 = (Comparable) o; // works
    System.out.println(s + " " + (String) s2); // works
    return;
  }
}
公共类ProcessArgs
{
公共静态T[]最小最大值(T…a)
{
对象[]mm=新对象[2];
mm[0]=a[0];
mm[1]=a[1];
if(mm[0]可比实例)
{
System.out.println(“Comparable”);//这是真的,在运行时打印Comparable
}
返回(T[])mm;//此处为运行时错误
/*运行时错误如下:
线程“main”中的可比异常
java.lang.ClassCastException:[Ljava.lang.Object;不能强制转换为[Ljava.lang.Compariable;
在ProcessArgs.minmax处(ProcessArgs.java:13)
位于ProcessArgs.main(ProcessArgs.java:18)
*/
}
公共静态void main(字符串[]args)
{
字符串[]sa=minmax(“你好”,“世界”);//错误,非法强制转换
System.out.println(sa[0]+sa[1]);
Object o=“Hello World”//有效-如果我们注释掉上面对minmax的方法调用
可比s=(可比)o;//有效
可比s2=(可比)o;//有效
System.out.println(s++(String)s2);//有效
返回;
}
}

它会抛出一个错误,因为您创建的实际类型,
Object[]
不是可比的
类型。Java泛型处理数组非常糟糕,如果可能,您应该尝试使用集合。在这种情况下,您可以使用反射创建适当类型的数组:

T[] mm = (T[]) Array.newInstance(a[0].getClass(), 2 );
鉴于这两条线:

Object o = "Hello World"; //works - if we comment out the method call to minmax above
Comparable<String> s = (Comparable) o; // works
Object o=“Hello World”//有效-如果我们注释掉上面对minmax的方法调用
可比s=(可比)o;//有效
第二行之所以有效,是因为字符串“Hello World”
实际上是一个可比较的


但是
Object[]
不是,它的类型是
Object[]
,所以它不能被强制转换。

只是给你一个提示,你可以比较下面的代码,了解代码中发生了什么

Object[] mm = new Object[2]; // reference type Object array and object type object array.
mm[0] = a[0]; // putting String value into 0th position, so it is comparable,
// but whole array is of type Object, so it is not able to cast it to String array while returning.

Object o = "Hello World"; // reference type Object and object type String
Object o = new String("Hello World"); // this code is also similar to above line.

注意:字符串是可比较的,但不是对象数组。

但是语句:if(mm[0]instanceof comparable)返回true,在我的代码中,T…a的泛型类型擦除是可比较的。此外:如果我将其从Object[]更改为:comparable[]mm=new comparable[2];而不是Object[],我在运行时仍然会出错[Ljava.lang.Compariable;无法强制转换为[Ljava.lang.String;mm[0]是数组中的一个元素。它不是数组本身,这是您稍后在代码中尝试强制转换的内容。即使您将
对象数组
更改为
Compariable数组
,在对
T[]进行强制转换时,返回值也会产生问题
是的,对此很抱歉。泛型和数组实际上并不混合。我添加了一个使用反射的正确示例。