简体   繁体   English

A <T extends B>和A <?有什么区别?延伸B>?

[英]What is the difference between A<T extends B> and A<? extends B>?

I am a new java learner. 我是一名新的java学习者。 Recently I was reading Generic programming and got my self confused with this... 最近我正在阅读Generic编程,让我对此感到困惑......

A<T extends B> and A<? extends B>

First of all, those are completely different constructs used in different contexts. 首先,这些是在不同环境中使用的完全不同的结构。

A<T extends B> is a part of generic type declaration such as A<T extends B>是泛型类型声明的一部分,例如

public class A<T extends B> { ... }

It declares generic type A with type parameter T , and introduces a bound on T , so that T must be a subtype of B . 它声明了类型参数为T泛型类型A ,并在T上引入了一个绑定,因此T必须是B的子类型。


A<? extends B> A<? extends B> is a parameterized type with wildcard, it can be used in variable and method declarations, etc, as a normal type: A<? extends B>是带有通配符的参数化类型,它可以在变量和方法声明等中使用,作为普通类型:

A<? extends B> a = ...;

public void foo(A<? extends B> a) { ... }

Variable declaration such as A<? extends B> a 变量声明如A<? extends B> a A<? extends B> a means that type of a is A parameterized with some subtype of B . A<? extends B> a装置,该类型的aA参数化的一些亚型B

For example, given this declaration 例如,鉴于此声明

List<? extends Number> l;

you can: 您可以:

  • Assign a List of some subtype of Number to l : Number的某个子类型的List分配给l

     l = new ArrayList<Integer>(); 
  • Get an object of type Number from that list: 从该列表中获取Number类型的对象:

     Number n = l.get(0); 

However, you can't put anything into list l since you don't know actual type parameter of the list: 但是,由于您不知道列表的实际类型参数,因此无法将任何内容放入列表l

Double d = ...;
l.add(d); // Won't compile

? is what is called a wildcard . 就是所谓的通配符 It means anything that extends B. 这意味着任何延伸B.

When you write List<T extends String> , your List can contains only elements of type T . 当您编写List<T extends String> ,您的List只能包含T类型的元素。

When you write List<? extends String> 当你写List<? extends String> List<? extends String> , your List can contains any element that extends String List<? extends String> ,您的List可以包含任何extends String元素

I hope I'm clear, since these concepts are complicated. 我希望我很清楚,因为这些概念很复杂。

(a long comment, not an answer) (长评,不是答案)

Totally different things. 完全不同的东西。 The similarity in syntax is a grave mistake made by Java. 语法的相似性是Java造成的严重错误。 And this mistake leads to a bigger mistake - many people try to understand wildcard as a type parameter (ie wildcard capture) 而这个错误会导致更大的错误 - 许多人试图将通配符理解为类型参数(即通配符捕获)

There was no such thing as A<? extends B> 没有A<? extends B> A<? extends B> until Java invented it. A<? extends B>直到Java发明它。 Until then the syntax used by researchers was A<B+> . 在此之前,研究人员使用的语法是A<B+> Java thought that it is too mysterious for our poor programmers, so it invented that syntax A<? extends B> Java认为这对我们糟糕的程序员来说太神秘了,所以它发明了语法A<? extends B> A<? extends B> that seems to read better on first round. A<? extends B>似乎读第一轮更好。

Well it is damn verbose and ugly. 嗯,这是多么冗长和丑陋。 If an API has a few wildcard, it looks like vomit of symbols. 如果API有一些通配符,它​​看起来像符号的呕吐物。

But the worse thing is the confusion it causes. 但最糟糕的是它引起的混乱。 It looks like a type parameter. 它看起来像一个类型参数。 And Java did that on purpose! Java是故意这样做的! Java did not believe that its programmers can ever understand covariant types, so syntactically it made the convariant types look like parameterized types, to guide programmers into the erroneous way of understanding, that, admittedly, can be useful in occasions, but ultimately makes people clueless. Java并不相信它的程序员可以理解协变类型,所以语法上它使得可变类型看起来像参数化类型,引导程序员进入错误的理解方式,不可否认,这在某些场合很有用,但最终会让人无能为力。

Generics is a complicated subject in general, and especially in Java. 泛型是一个复杂的主题,特别是在Java中。 But basically the difference is: 但基本上区别在于:

T extends B T延伸B

There is a specific type T, it is just limited to being B or a subclass of B, but it is a specific know type. 有一个特定的类型T,它仅限于B或B的子类,但它是一个特定的知识类型。 Any plain old generic declaration is like saying: <T extends Object> By saying T extends B, we are saying that T is more limited than any object, it has to specifically be a type of B. 任何普通的旧泛型声明都像是这样说: <T extends Object>通过说T扩展B,我们说T比任何对象都更有限,它必须特别是B的类型。

? extends B 延伸B.

This means that the generic type is unknown, exactly, but what we can say about it is that it extends B. It may be B, it may be a subclass of B. With a wildcard and the word extends, it means that you can get B out of the object, but you cannot put anything in the object in a type safe way. 这意味着泛型类型是未知的,确切地说,但我们可以说它是扩展B.它可能是B,它可能是B的子类。使用通配符和单词extends,它意味着你可以从对象中获取B,但是你不能以类型安全的方式在对象中放置任何东西。 (? super B means the opposite - you can put something in a method parameter that is a B or a superclass of B, but you cannot be sure what the return value of a method would be.) (?super B意味着相反 - 你可以把一些东西放在B的B或B的超类的方法参数中,但你不能确定方法的返回值是什么。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 之间有什么区别<? extends Base>和<T extends Base> ? - What is the difference between <? extends Base> and <T extends Base>? “有什么区别?” 延伸E“和”T延伸E“? - What is the difference between “? extends E” and “T extends E”? 类有什么区别<? extends T>和班级<? extends ?>在爪哇? - What is the difference between Class<? extends T> and Class<? extends ?> in Java? 有什么区别<t extends foo>和<!--? extends Foo--> ?</t> - What difference between <T extends Foo> and <? extends Foo>? &lt;extended Comparable&gt;和&lt;extended Comparable &lt;T &gt;&gt;之间的区别? - difference between < extends Comparable > and < extends Comparable < T > >? 新列表<A & ? extends B>();</a> - new List<A & ? extends B>(); 通配符类型,类型擦除和运行时签名:发生什么情况 <T extends A & B> A和B在哪里继承共同的祖先? - Wildcard types, type erasure and runtime signature: what happens on <T extends A & B> where A and B inherit a common ancestor? Mapstruct:如何映射A扩展SingleValue <T> 到T和A扩展SingleValue <T> 到B扩展SingleValue <T> 使用相同的映射器? - Mapstruct: How to map A extends SingleValue<T> to T and A extends SingleValue<T> to B extends SingleValue<T> with the same mapper? (a!= b)和(a!=(a = b))之间有什么区别? - What is the difference between (a != b) and (a != (a = b)? “&”或“,”:A之间有什么区别 <T extends I1 & I2> 和A. <T extends I1 , I2> - “&” or “,”: What is the difference between A<T extends I1 & I2> and A<T extends I1 , I2>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM