为什么我super只能使用通配符而不使用类型参数?
例如,在Collection界面中,为什么toArray方法不是这样写的
interface Collection<T>{
<S super T> S[] toArray(S[] a);
}
Run Code Online (Sandbox Code Playgroud) 我只是看看List界面中定义的方法:<T> T[] toArray(T[] a)
我有一个问题.为什么它是通用的?因此,方法不完全是类型安全的.以下代码片段编译但导致ArrayStoreException:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
String[] stringArray = list.toArray(new String[]{});
Run Code Online (Sandbox Code Playgroud)
在我看来,如果toArray不是通用的并采用List类型参数,那就更好了.
我已经写过玩具示例,它可以通用:
package test;
import java.util.Arrays;
public class TestGenerics<E> {
private Object[] elementData = new Object[10];
private int size = 0;
public void add(E e) {
elementData[size++] = e;
}
@SuppressWarnings("unchecked")
//I took this code from ArrayList but it is not generic
public E[] toArray(E[] a) {
if (a.length < size)
// Make a new array of a's runtime type, …Run Code Online (Sandbox Code Playgroud) toArray方法隐藏<E>传递给Collection<E>接口.以下是方法签名.
<T> T[] toArray(T[] a);
Run Code Online (Sandbox Code Playgroud)
因为以下是可能的.并将结果转化为ArrayStoreException
ArrayList<String> string = new ArrayList<String>();
string.add("1");
string.add("2");
Integer intArray[] = new Integer[2];
intArray = string.toArray(intArray);
Run Code Online (Sandbox Code Playgroud)
我想知道为什么会做出这样的决定?为什么在设计API时允许这样的情况?无论如何这个代码导致了RuntimeException?
为什么Object[].class.isAssignableFrom(String[].class) == true,有String[].getSuperClass()或getGenericInterfaces()无法得到Object[]?
我检查了JDK的来源,但我认为我自己无法得到答案.现在,我知道JDK使用树来存储类之间的关系,并使用深度来指示它的级别,Class::isAssignableFrom()搜索链,所以绝对数组在那个树中.并且还String[]连接到Object[].
我可以说那String[]是一个子类Object[]吗?或者它只是Java的另一个奇怪的东西?