那么为什么我们可以实例化 Pair 但我们不能实例化 Pair
Pair<T> p=new Pair<T>();
VS
Pair<?> p=new Pair<?>();
我知道这<?>
意味着未知类型--><? extends Object>
但<T>
意思不一样---><T extends Object>
有人有想法吗?
那么为什么我们可以实例化 Pair 但我们不能实例化 Pair
Pair<T> p=new Pair<T>();
VS
Pair<?> p=new Pair<?>();
我知道这<?>
意味着未知类型--><? extends Object>
但<T>
意思不一样---><T extends Object>
有人有想法吗?
<T>
本身并不意味着什么。T
类型必须在某个地方定义,无论是在您的类还是方法级别,例如:
public class PairFactory<T> {
public Pair<T> makePair() {
return new Pair<T>();
}
}
在这种情况下,您<T>
在实例化期间决定:
new PairFactory<String>();
这涉及更多:
public <T> Pair<T> makePair() {
return new Pair<T>();
}
编译器将尝试根据上下文找出类型,例如:
Pair<Date> p = makePair();
不, ?和 T 不是一回事。? 表示通配符泛型类型参数——它可以是运行时的任何东西。T
表示在运行时将是特定类型的泛型类型参数——我们只是在编译时不知道它。
也就是说,aList<?>
可以包含字符串、整数、浮点数等。AList<T>
只能包含T
参数化为的任何内容。
不允许使用通配符作为参数进行实例化,因为它通常是无用的。相反,您可以只使用类型参数范围内的任何引用类型(在这种情况下,没有边界,所以任何引用类型都可以):
class SuperCrazyBogusType { }
Pair<?> p = new Pair<SuperCrazyBogusType>();
(或者您可以使用更普通的类型,例如Object
)。
你知道这有多奇怪吗?是的,您可以使用任何任意类型进行实例化,即使是与您的程序的其余部分或您正在做的事情无关的类型。是的,它是 100% 安全和正确的,因为你想要的只是一个Pair<?>
(一对未知类型)。
这指出了为什么它是荒谬的,以及为什么这样做的语法是不必要的。几乎没有什么可以用Pair<?>
你得到的(例如你不能把任何数据放进去),因为你不知道类型参数。