这句话的措辞和格式有点不走运*。 answer by Maouven 中的链接实际上很好地涵盖了一般主题,但可以尝试在这里关注 Java 和通配符的特殊情况:
通配符是存在类型的受限形式。给定一个泛型类型声明 G,G 大致类似于 Some X <: b. g.>
这基本上说G 的类型参数是B 的任何子类型。这是总是的情况,即使你没有明确地说出来。
考虑以下 sn-p,希望能说明这一点:
class B { }
class G<T extends B>
{
T get() { return null; }
}
public class Example
{
public static void main(String[] args)
{
G<?> g = null;
// This works, even though "G<?>" seemingly does not say
// anything about the type parameter:
B b = g.get();
}
}
通过调用g.get() 获得的对象是B 类型,因为G<T extends B> 的声明 保证任何类型参数(即使它是? 通配符)总是“至少”类型为B。
(与此相反:如果声明只有G<T>,那么从g.get()获得的类型将只有Object类型)
这种关系被描述为与类型理论符号“大致相似”。你大概可以这样想象:如果声明是G<T extends B>,而你使用了G<?>类型,那么这大致(!)的意思是:存在一个类型X extends B,而这里的?代表这个(未知)输入X。
旁白:请注意,这也指的是Insersection Types。如果你将类声明为class G<T extends B & Runnable>,那么语句
B b = g.get();
Runnable x = g.get();
两者都有效。
*“倒霉”的格式是指这一段的源代码实际上是这样写的
... is roughly analogous to <span class="type">Some <span class="type">X</span> ...
更清楚地表明“Some”这个词已经是那里正式定义的类型的一部分......