为了账号安全,请及时绑定邮箱和手机立即绑定

为什么“集合”不简单地视为“集合<”>

为什么“集合”不简单地视为“集合<”>

largeQ 2022-09-21 17:31:25

考虑以下 API 方法,该方法取自 Shiro 的组织.apache.shiro.主题.Principal 收集接口,但也可能存在于其他库中:

Collection fromRealm(String realmName);

是的,即使现在仍然有使用原始类型的库,可能是为了保持Java 1.5之前的兼容性?!

如果我现在想将此方法与流或可选选项一起使用,如下所示:

principals.fromRealm(realmName).stream().collect(Collectors.toSet());

我收到有关未选中转换和使用原始类型的警告,并且我更喜欢使用参数化类型。

日蚀:

类型安全:方法收集(收集器)属于原始类型流。对泛型类型 Stream<T> 的引用应参数化

爪哇:

注意:泛型测试.java使用未经检查或不安全的操作。

由于我无法更改API方法的签名以摆脱此警告,因此我可以注释或简单地转换为如下所示:@SuppressWarnings("unchecked")Collection<?>

((Collection<?>) principals.fromRealm(realmName)).stream().collect(Collectors.toSet());

由于这种转换当然总是有效的,我想知道为什么编译器不是简单地对待而是警告这种情况。添加批注或强制转换不会稍微改进代码,但会降低可读性,甚至可能隐藏有关使用非参数化类型的实际有效警告。CollectionCollection<?>



查看完整描述

4 回答

?
莫回无

TA贡献1554条经验 获得超7个赞

原因很简单:

您可以从与 从 相同的方式读取 s。但是你不能将s添加到a(编译器禁止这样做),而在a中你可以。ObjectCollection<?>CollectionObjectCollection<?>Collection

如果在Java 5发布后,编译器已经将每个翻译成,那么以前编写的代码将不再编译,从而破坏向后兼容性。CollectionCollection<?>


查看完整回答
反对 回复 2022-09-21
?
慕容森

TA贡献1485条经验 获得超17个赞

原始类型和无界通配符之间的主要区别在于后者是类型安全的,也就是说,在编译级别,它检查集合中的项是否属于同一类型。编译器不允许您将字符串和整数添加到通配符类型的集合中,但它允许您执行以下操作:<?>

List raw = new ArrayList();
raw.add("");
raw.add(1);

实际上,在无界通配符集合()的情况下,您根本无法向列表中添加任何内容,但是(来自Oracle文档):List<?> wildcard = new ArrayList<String>()null

由于我们不知道c的元素类型代表什么,因此我们无法向其添加对象。add() 方法采用类型为 E 的参数,即集合的元素类型。当实际类型参数为 ?时,它代表某个未知类型。我们传递要添加的任何参数都必须是此未知类型的子类型。由于我们不知道那是什么类型,因此我们无法传递任何内容。唯一的例外是 null,它是每种类型的成员。


查看完整回答
反对 回复 2022-09-21
?
互换的青春

TA贡献1461条经验 获得超6个赞

尖叫:Collection<?>

请不要向我添加任何内容。我有一个严格的内容类型,...嗯,呃,我只是忘了它是什么类型。

而 a 说:Collection

这一切都很酷!你可以添加任何你喜欢的东西,我没有限制。

那么,为什么编译器不应该转换为?因为它会带来很多限制。CollectionCollection<?>


查看完整回答
反对 回复 2022-09-21
?
繁华开满天机

TA贡献1486条经验 获得超4个赞

一个我能想到的用例,为什么不被认为是假设我们有一个实例CollectionCollection<?>ArrayList

现在,如果实例的类型为 or 或 ,则可以仅添加该类型(类型检查)。 不等效于 。ArrayList<Integer>ArrayList<Double>ArrayList<String>ArrayList<?>ArrayList<Object>

但是只有 ,您可以添加任何类型的对象。这可能是编译器不考虑作为(类型检查)的原因之一。ArrayListArrayListArrayList<?>

另一个原因可能是与没有泛型的Java版本向后兼容。


查看完整回答
反对 回复 2022-09-21

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信