A 和A ?
我是一名新的java学习者。 最近我正在阅读Generic编程,让我对此感到困惑……
A and A
首先,这些是在不同环境中使用的完全不同的结构。
A
是generics类型声明的一部分,例如
public class A { ... }
它声明了类型参数为T
generics类型A
,并在T
上引入了一个绑定,因此T
必须是B
的子类型。
A extends B>
A extends B>
是带有通配符的参数化类型,它可以在变量和方法声明等中使用,作为普通类型:
A extends B> a = ...; public void foo(A extends B> a) { ... }
变量声明如A extends B> a
A extends B> a
表示A extends B> a
类型是A
参数化为B
某个子类型。
例如,鉴于此声明
List extends Number> l;
您可以:
-
将
Number
的某个子类型的List
分配给l
:l = new ArrayList
(); -
从该列表中获取
Number
类型的对象:Number n = l.get(0);
但是,您不能将任何内容放入列表l
因为您不知道列表的实际类型参数:
Double d = ...; l.add(d); // Won't compile
?
就是所谓的通配符 。 这意味着任何延伸B.
当您编写List
,您的List
只能包含T
类型的元素。
当你写List extends String>
List extends String>
,您的List
可以包含任何extends String
元素
我希望我很清楚,因为这些概念很复杂。
(长评,不是答案)
完全不同的东西。 语法的相似性是Java所犯的严重错误。 而这个错误会导致更大的错误 – 许多人试图将通配符理解为类型参数(即通配符捕获)
没有A extends B>
A extends B>
直到Java发明它。 在此之前,研究人员使用的语法是A
。 Java认为这对我们糟糕的程序员来说太神秘了,所以它发明了语法A extends B>
A extends B>
在第一轮似乎更好看。
嗯,这是多么冗长和丑陋。 如果API有一些通配符,它看起来像符号的呕吐物。
但最糟糕的是它引起的混乱。 它看起来像一个类型参数。 Java是故意这样做的! Java并不相信它的程序员可以理解协变类型,所以语法上它使得可变类型看起来像参数化类型,引导程序员进入错误的理解方式,不可否认,这在某些场合很有用,但最终会让人无能为力。
generics通常是一个复杂的主题,特别是在Java中。 但基本上区别在于:
T延伸B
有一个特定的类型T,它仅限于B或B的子类,但它是一个特定的知识类型。 任何普通的旧generics声明都像是这样说:
通过说T扩展B,我们说T比任何对象更有限,它必须特别是B的类型。
? 延伸B.
这意味着generics类型是未知的,确切地说,但我们可以说它是扩展B.它可能是B,它可能是B的子类。使用通配符和单词extends,它意味着你可以从对象中获取B,但是你不能以类型安全的方式在对象中放置任何东西。 (?super B意思相反 – 你可以把一些东西放在B的B或B的超类的方法参数中,但你不能确定方法的返回值是什么。)
- Java Generics Reflection:子类的通用字段类型
- 如果我在编译时不知道该类,如何获得Enum的值?
- 对于java参数/返回类型,C ++相当于使用
- 如何以通用方式处理数字?
- Java Generic / Type Dispatch Question
- `copy(List dest,List src)`和`copy(List dest,List src)之间的区别
- 是什么意思
save(S entity); 在Spring Repository中? - 在进行通用转换时,在generics方法中捕获ClassCastException
- 你能把一个int数组传递给java中的generics方法吗?