java-泛型类型和toArrayMethod

我有一班MyStack< T>它定义了以下内容

public T[] toArray(){
  int s=size();
  @SuppressWarnings("unchecked")
  T[] result=(T[])new Object[s];
  Node n=first;
  for (int i=0; i<s; i++){
     result[i]=n.data;
     n=n.next;
  }
  return result;
}

由于这将返回类型T的数组,因此我认为如果声明了此实例:MyStack< String> s = new MyStack<&gt ;,以下将是完全有效的:String [] test = s.toArray().我认为这是因为s的类型为String,所以toArray应该返回String类型的数组,因为String基本上已经替换了此类中的每个T(我知道仅适用于此特定实例化).没有错误的唯一运行方式是执行以下操作:Object [] test = s.toArray(). 为什么是这样?

解决方法:

好吧,等一下.假设您的假设是正确的,即每个T都用String代替.

以下强制转换有效吗?

String[] result = (String[])new Object[s];

不,不会.我们可以确定新的Object []不是String [].

现在有时您会看到类似(T [])new Object [n]的信息,但它仅能正常工作,因为强制转换实际上在通用类内部变为erased. (这是一种欺骗性的习语.)

编译该类时,实际上发生的是用T的上限替换对T的引用(除非您有< T扩展...>之类的信息,否则可能是Object):

public Object[] toArray(){
  int s=size();
  Object[] result=new Object[s];
  Node n=first;
  for (int i=0; i<s; i++){
     result[i]=n.data;
     n=n.next;
  }
  return result;
}

并将演员表移至呼叫站点:

MyStack stack = new MyStack();
String[] arr = (String[])stack.toArray();

因此,实际上,尽管在类内部擦除了强制类型转换,但一旦将值返回到抛出ClassCastException的类外部,强制类型转换便会发生.

通常无法实例化数组(通常是对象)的原因是Collections框架定义其toArray方法以将return数组作为参数的原因.一个简单的版本如下所示:

public T[] toArray(T[] inArray){
    int s = size();

    Node n = first;
    for (int i = 0; i < s; i++){
        inArray[i] = n.data;
        n = n.next;
    }

    return inArray;
}

有关如何通用创建数组的一些想法,您可能会看到‘How to create a generic array in Java?’;有关如何创建数组的一些想法,请参阅但是,您将需要调用方将一些参数传递给方法.

上一篇:Java中的数据类型及其表示


下一篇:Python继承的类型变量