Collections.min/max方法的签名
在 Java 中,Collections 类包含以下方法:
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)
它的签名因其对泛型的高级使用而闻名, 以至于在《Java in a Nutshell》一书中提到过 以及官方的 Sun 泛型教程。
但是,我找不到以下问题的令人信服的答案:
为什么形式参数是 Collection< 类型?扩展 T>
,而是 比集合
?有什么额外的好处?
In Java, the Collections class contains the following method:
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> c)
Its signature is well-known for its advanced use of generics,
so much that it is mentioned in the Java in a Nutshell book
and in the official Sun Generics Tutorial.
However, I could not find a convincing answer to the following question:
Why is the formal parameter of type Collection<? extends T>
, rather
than Collection<T>
? What's the added benefit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
类型推断是一个棘手的话题,我承认我对此了解不多。但是,请检查此示例:
考虑 min() 的第一个签名允许调用编译,而第二个签名则不允许。这不是一个非常实际的示例,因为人们必须问为什么我要显式地将方法键入
,但也许有一个隐含的推论,其中
B
将是推断的类型。Type inference is a tricky topic that I'll admit that I don't know that much about. However, examine this example:
Consider that the first signature of min() allows the call to compile whereas the second does not. This isn't a very practical example, since one must ask why I would be explicitly typing the method to
<B>
, but perhaps there is an implicit inference whereB
would be the inferred type.?
的好处之一是它禁止向Collection
添加项目One benefit of the
?
is that it prohibits additions of items to theCollection
我认为它实际上并没有为您提供此方法的更多信息,但是当 T 是类的一部分而不仅仅是静态方法时,这是一个好习惯。
他们将其包含在这里,以便它可以成为新的约定,其中每个泛型都应该扩展为 ?
T 类应该遵循 PECS:什么是 PECS(生产者扩展消费者超级)?
但静态方法不需要(至少参数,返回值应该总是)
I think it actually doesn't give you anything more for this method, however its a good habit to get into when T is part of the class and not just a static method.
They are including it here so it can become the new convention where every generic should be extended by ?
A class of T should follow PECS: What is PECS (Producer Extends Consumer Super)?
But a static method doesn't need to (at least the parameters, the return value should always)
这是为了支持 Java 1.4(及之前版本)中方法的遗留签名。
在 Java 5 之前,这些方法的签名是
具有多个边界,擦除规则使第一个边界成为方法的原始类型,因此如果没有
Object &
签名将会是,并且遗留代码将被破坏。
这摘自 O'Reilly 的 Java Generics and Collections 书,第 3.6 章
This is to support a legacy signature of the method in Java 1.4 ( and before ).
Prior to Java 5 the signature for these methods was
With multiple bounds the erasure rules make the first bound the raw type of the method, so without
Object &
the signature would beand legacy code would break.
This is taken from O'Reilly's Java Generics and Collections book, chapter 3.6
根据我对 Mark 的回答的评论,如果您有类似的内容,
则更清楚 min 返回 A 类型的对象(实际签名为
A Play.min(Collection c)
)。如果您将min(Collection)
保留为不带扩展部分,则Play.min(coll)
将具有以下签名? extends A Play.min(Collection c)
不太清楚。Building on the comments I put on Mark's answer, if you have something like
It's clearer that min returns an object of type A (the actual signature is
<A> A Play.min(Collection<? extends A> c)
). If you leavemin(Collection<T>)
without the extends part thenPlay.min(coll)
will have the following signature<? extends A> ? extends A Play.min(Collection<? extends A> c)
which isn't as clear.