![]() |
1
167
第一种说法是“某种类型,它是e的祖先”;第二种说法是“某种类型,它是e的一个子类”。(在这两种情况下,E本身是可以的。)
因此,构造函数使用
例如,假设您有这样的类层次结构:
和A
同样,您也可以将队列排入
|
![]() |
2
106
这是基于Java如何实现泛型的原因。 数组示例 使用数组可以这样做(数组是协变的)
但是,如果你尝试这样做会发生什么?
最后一行编译得很好,但是如果运行此代码,可以
这意味着您可以愚弄编译器,但不能愚弄运行时类型系统。这是因为数组就是我们所说的
可赎回类型
.这意味着在运行时Java知道这个数组实际上是实例化的整数数组,它恰好是通过类型引用访问的。
所以,正如你所看到的,一件事是对象的实际类型,另一件事是你用来访问它的引用的类型,对吗? Java泛型的问题 现在,Java泛型类型的问题是,类型信息被编译器丢弃,并且在运行时不可用。此过程称为 type erasure . 在Java中实现类似这样的泛型是有充分理由的,但这是一个很长的故事,它与二进制代码兼容性与预先存在的代码有关。 但这里重要的一点是,由于在运行时没有类型信息,因此无法确保我们没有提交堆污染。 例如,
如果Java编译器不阻止您这样做,运行时类型系统也不能阻止您,因为在运行时没有办法确定该列表仅是整数列表。Java运行时会让你把任何你想要的东西放进这个列表中,当它只包含整数时,因为当它被创建时,它被声明为整数列表。 这样,Java的设计者就确保了你不能愚弄编译器。如果你不能愚弄编译器(我们可以用数组),你也不能愚弄运行时类型系统。 因此,我们认为泛型类型是 不可具体化的 . 显然,这会阻碍多态性。请考虑以下示例:
现在您可以这样使用它:
但是,如果尝试用泛型集合实现相同的代码,则不会成功:
如果你试图…
解决方案是学会使用Java泛型的两个强大的特征,即协方差和逆变。 协方差 使用协方差,您可以从结构中读取项,但不能在其中写入任何内容。所有这些都是有效的声明。
你可以从
因为您可以确保无论实际列表包含什么,都可以将其转换为一个数字(扩展数字的所有内容都是一个数字,对吗?) 但是,不允许将任何内容放入协变结构中。
这是不允许的,因为Java不能保证泛型结构中对象的实际类型。它可以是扩展数字的任何东西,但编译器不能确定。所以你可以读,但不能写。 逆变 相反,你可以做相反的事情。您可以将事物放入通用结构中,但不能从中读出。
在这种情况下,对象的实际性质是一个对象列表,通过反差,您可以将数字放入其中,基本上是因为所有的数字都将对象作为它们的共同祖先。因此,所有数字都是对象,因此这是有效的。 但是,假设您将得到一个数字,那么您就不能安全地从这个逆向结构中读取任何内容。
如您所见,如果编译器允许您编写这一行,那么您将在运行时得到一个ClassCastException。 获取/输出原则 因此,当您只打算将泛型值从结构中取出时,请使用协方差;当您只打算将泛型值放入结构中时,请使用协方差;当您打算同时执行这两项操作时,请使用完全相同的泛型类型。 我有一个最好的例子,它可以将任何类型的数字从一个列表复制到另一个列表中。只有它 得到 源中的项,仅此 放 目标中的项。
由于协方差和反方差的力量,这种方法适用于这样的情况:
|
![]() |
3
46
|
![]() |
4
11
我要试着回答这个问题。但要得到一个很好的答案,你应该检查Joshua Bloch的书有效Java(第二版)。他描述了助记词pecs,它代表“生产者延伸,消费者超级”。 其思想是,如果代码使用的是来自对象的泛型值,那么应该使用扩展。但是,如果要为泛型类型生成新值,则应使用super。 例如:
和
但你真的应该看看这本书: http://java.sun.com/docs/books/effective/ |
![]() |
5
9
|
![]() |
6
7
你可能
want to google for the terms
逆变
(
就像你想增加一个
您还应该能够添加
但是你应该意识到
一旦你有了这个,很容易想到你想要的场景
逆变
也检查
|
![]() |
7
4
在回答之前,请明确
例子:
希望这能帮助您更清楚地理解通配符。
|
![]() |
8
3
带有上界的通配符看起来像“?扩展类型“并表示作为类型子类型的所有类型的族,类型类型类型包含在内。类型被称为上界。 带有下限的通配符看起来像“?“超级类型”,代表所有类型的族,这些类型是类型的超级类型,包括类型类型类型。类型被称为下限。 |
![]() |
9
0
您有一个父类和一个从父类继承的子类。父类是从另一个名为祖父母类的类继承的。因此继承顺序是祖父母>父>子级。 现在, &?扩展父类-这接受父类或子类 &?超级父级>-这接受父级或祖父母级 |
|
user29759326 · 如何返回递归函数中的最后一个值? 3 月前 |
|
malife89 · 将java中的字符串读取为正确的日期格式 3 月前 |
![]() |
Tim · 在java中,有没有更快的方法将字节数组写入文件? 3 月前 |
![]() |
rudraraj · java中未声明最终变量 4 月前 |
![]() |
Bala Ji · 以下BFS的实施效率如何? 4 月前 |