为什么表达式?[]
非法?我不明白为什么它比T[]
更令人怀疑。我知道通用数组创建存在问题,所以我明白为什么不允许使用new T[]
和new ?[3]
之类的内容,但我不知道{{1}有什么问题。 }。例如,能够拥有像?[]
这样的方法签名会很好。这有什么不对?
另外,编写一个采用未知类型数组的方法的首选方法是什么?你应该使用
吗?void method(?[] arr)
优先于
public void method(Object[] arr)
或者这是常规规则的一个例外,如果类型参数只出现一次,你应该避免在方法签名中输入参数吗?
答案 0 :(得分:3)
是的,您应该使用
public void method(Object[] arr)
优先于
public <T> void method(T[] arr)
因为它们都接受相同的潜在参数集,第一个更简单且类型参数更少。
为什么表达式
?[]
非法?
从语法上讲,因为[]
的左侧必须是实际类型。从语言上讲,这是因为没有必要,你可以改用Object[]
。
一般情况下,只要你想做(? extends X)[]
这样的事情,在你的脑海中,只需将其转换为X[]
即可。同样,只要您想将? extends X
这样的内容用作独立类型,请考虑使用X
。
对于泛型类型参数,需要? extends X
,因为泛型类型不是协变的(List<A>
不是List<B>
的子类型,即使A
是B
的子类型1}})。但是,数组类型是协变的(如果A[]
是B[]
的子类型,A
是B
的子类型,因此不需要(? extends X)[]
。
答案 1 :(得分:1)
您正在混合类型参数和类型参数!
考虑以下泛型类型List
的示例:
interface List<T> {
void add(T element);
int size();
T get(int index);
}
此处,T
是类型参数。它是“真实”类型的占位符,在实例化泛型类型时“填充”。您可以在泛型类型的实现中使用此占位符,例如声明一个变量,或作为另一个泛型类型的类型参数:
class LinkedList<T> implements List<T> {
private Node<T> head; // here, T is the type argument of E in Node<E>
...
}
class Node<E> {
private E element; // here, E is a placeholder for the 'real' type
...
}
类型参数是形式参数,如element
是上例中方法add
的形式参数。它只是运行时指定的值的占位符!
现在让我们使用泛型类型:
List<String> list = new LinkedList<String>();
此处,String
是类型参数,它取代了泛型类型的类型参数T
。
通配符('?')也是某种类型的参数,表示具体类型未知(且不相关)。因此,您可以在实例化泛型类型时使用它:
List<?> list = new LinkedList<String>();
同样,?
是类型参数,因此您无法像类型参数那样使用它!