首页 文章

Java泛型的类型参数中的问号是什么意思?

提问于
浏览
174

这是从斯坦福分析器附带的一些示例中获取的一小段代码 . 我已经用Java开发了大约4年,但是从来没有对这种代码风格应该表明什么有非常强烈的理解 .

List<? extends HasWord> wordList = toke.tokenize();

我并不担心代码的细节 . 令我困惑的是,通用表达式应该用英语表达的是什么 .

谁可以给我解释一下这个?

6 回答

  • 12

    List<? extends HasWord> 接受任何扩展HasWord的具体类 . 如果您有以下课程......

    public class A extends HasWord { .. }
    public class B extends HasWord { .. }
    public class C { .. }
    public class D extends SomeOtherWord { .. }
    

    ... wordList 只能包含As或Bs的列表或两者的混合,因为这两个类都扩展了相同的父级或 null (无法检查 HasWorld 的instanceof) .

  • 191

    问号是'any type'的能指 . ? 独自意味着

    任何类型扩展Object(包括Object)

    而你上面的例子意味着

    任何扩展或实现HasWord的类型(如果HasWord是非抽象类,则包括HasWord)

  • 1

    问号用于定义通配符 . 查看有关它们的Oracle文档:http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

  • 4
    ? extends HasWord
    

    表示“扩展 HasWord 的类/接口” . 换句话说, HasWord 本身或其任何一个孩子......基本上任何与 instanceof HasWordnull 一起使用的东西 .

    在更多技术术语中, ? extends HasWord 是有界通配符,涵盖在Effective Java 3rd Edition的第31项中,从第139页开始 . 第2版的同一章是available online as a PDF;有界通配符上的部分是从第134页开始的第28项 .

    更新:PDF链接已更新,因为Oracle在一段时间后删除了它 . 它现在指向由伦敦玛丽女王大学电子工程和计算机科学学院主办的副本 .

    更新2:让我们详细了解您为什么要使用通配符 .

    如果您声明一个其签名希望您传入 List<HasWord> 的方法,那么您唯一可以传入的是 List<HasWord> .

    但是,如果所述签名是 List<? extends HasWord> ,则可以传入 List<ChildOfHasWord> .

    请注意 List<? extends HasWord>List<? super HasWord> 之间存在细微差别 . 正如Joshua Bloch所说:PECS = 生产环境 者延伸,消费者超级 .

    这意味着如果你传入一个集合,你的方法从中提取数据(即集合正在为你的方法生成元素),你应该使用 extends . 如果您传入的方法是您的方法添加数据(即集合正在消耗您的方法创建的元素),则应使用 super .

    这可能听起来令人困惑 . 但是,您可以在 Listsort命令中看到它(这只是Collections.sort的两个arg版本的快捷方式) . 它实际上需要 Comparator<? super T> 而不是 Comparator<T> . 在这种情况下,比较器正在使用 List 的元素,以便重新排序List本身 .

  • 9

    也许一个人为的“现实世界”的例子会有所帮助 .

    在工作中,我们有不同口味的垃圾箱 . 所有垃圾箱都含有垃圾,但有些垃圾箱是专家,不会带走所有类型的垃圾 . 所以我们有 Bin<CupRubbish>Bin<RecylcableRubbsih> . 类型系统需要确保我不能将 HalfEatenSandwichRubbish 放入这些类型中的任何一种,但它可以进入一个普通的垃圾箱``Bin . If I wanted to talk about a Bin of Rubbish which may be a specialist so I can't put in incompatible rubbish, then that would be Bin` .

    (注意: ? extends 并不意味着只读 . 例如,我可以采取适当的预防措施从一个未知专业的垃圾箱中取出一块垃圾,然后将其放回另一个地方 . )

    不知道有多大帮助 . 存在多态性的指针指针并不完全明显 .

  • 51

    用英语讲:

    它是扩展HasWord类的某种类型的List,包括HasWord

    通常,泛型中的 ? 表示任何类 . 并且 extends SomeClass 指定该对象必须扩展 SomeClass (或者是该类) .

相关问题