java - 为什么 A->B 不构成 List<A>->List<B>?这不会消除对通配符的需要吗?

标签 java c++ templates generics covariance

免责声明:我不是专业开发人员,也不打算成为一名专业开发人员。阅读有关 Java 的书籍,因为我想尝试 Android 编程,以前没有任何 Java 经验。

我正在阅读this book - 我比较喜欢它。我已经阅读了有关泛型类的章节的一部分,到了他们提到通配符的地步,并且感到困惑。

如果 B 扩展 A:

  1. List<B> 不是 List<A> 的子类型(据我了解,它们是完全相同的)
  2. List<? extends B>List<? extends A> 的子类型

后者允许编写接受泛型类型参数的函数 - 例如 List<? extends A> 。此类函数将接受 List<B> 的参数或List<A> .

现在,回答我的问题:

以类似于 C++ 的方式(以"template"风格)实现泛型不是更简单吗?这将使 List<B>List<A>两种不同的类型,它们将以预期的方式相关。这也允许在函数中简单地声明您期望参数的类型为 List<A> ,这将允许 List<B>正好适合那里。

我猜这背后不仅仅是“我们讨厌 C++,让我们让事情变得不同” :) 也很可能我还不知道某些东西,这使得通配符成为一个奇妙的东西和有用的工具。您对此有何看法?

编辑:如果您提到List<X>在你的答案中,记得使用反引号,以避免 <X>被解释为 HTML 标记。

最佳答案

原因很简单。

假设您有一个 List<A> 类型的变量。假设List<B>确实是 List<A> 的子类型。

这意味着什么时候这是合法的:

List<A> a_list;
a_list = new List<B>(); //allowed when List<B> is subtype of list<A>
a_list.add(new A()); // WOAH!

当我说“WOAH”时,会发生以下情况:您将 A 类型的项目添加到 a_list 中。由于 a_list 被声明为 List<A> ,这应该是合法的。但是等等:a_list 指向 List<B> 类型的东西。

现在我们将 A 类型的内容添加到应该仅存储 B 类型的项目的列表中,这显然不是我们想要的,因为 A 不是 B 的子类!

关于java - 为什么 A->B 不构成 List<A>->List<B>?这不会消除对通配符的需要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4229886/

相关文章:

java - 哪个Java库提供base64编码/解码?

java - 我可以使用哪个开源 Java 库来构建贝叶斯网络?

抛出异常时的 Java 最佳实践 : throwing core Java exceptions

c++ - 类模板需要模板参数列表

css - 乔姆拉。编辑器在里面添加带有 css 规则的标签,我只想要标签!

arrays - 在字典中列出作为模板定义

java - Android - ListView onItemClick() 未在 4.1 jellybean 中触发

c++ - 被 C++ 逻辑或 (||) 运算符混淆

c++ - 可变类的文件包含问题

c++ - 如何从 system_clock::time_point 设置系统时间