Java 泛型谜题,扩展类并使用通配符

2024-02-23

一段时间以来,我一直在努力解决这个问题,并认为也许一些新人会看到这个问题;谢谢你的时间。

import java.util.*;

class Tbin<T> extends ArrayList<T> {}
class TbinList<T> extends ArrayList<Tbin<T>> {}

class Base {}
class Derived extends Base {}

public class Test {
  public static void main(String[] args) {
    ArrayList<Tbin<? extends Base>> test = new ArrayList<>();
    test.add(new Tbin<Derived>());

    TbinList<? extends Base> test2 = new TbinList<>();
    test2.add(new Tbin<Derived>());
  }
}

使用 Java 8。在我看来,就像直接创建容器一样test相当于容器中test2,但编译器说:

Test.java:15: error: no suitable method found for add(Tbin<Derived>)
    test2.add(new Tbin<Derived>());
         ^

我该怎么写Tbin and TbinList那么最后一行可以接受吗?

请注意,我实际上会添加键入的Tbin这就是为什么我指定Tbin<Derived>在最后一行。


发生这种情况是因为方式捕获转换 http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.10 works:

There exists a capture conversion from a parameterized type G<T1,...,Tn> to a parameterized type G<S1,...,Sn>, where, for 1 ≤ i ≤ n :

  • If Ti is a wildcard type argument of the form ? extends Bi, then Si is a fresh type variable [...].

捕获转换不会递归应用。

注意结束位。那么,这意味着,给定这样的类型:

    Map<?, List<?>>
//      │  │    └ no capture (not applied recursively)
//      │  └ T2 is not a wildcard
//      └ T1 is a wildcard

仅捕获“外部”通配符。这Map键通配符被捕获,但是List元素通配符不是。这就是为什么我们可以添加到List<List<?>>,但不是一个List<?>。通配符的位置很重要。

将此转移到TbinList,如果我们有一个ArrayList<Tbin<?>>,通配符位于不会被捕获的地方,但是如果我们有一个TbinList<?>,通配符位于它被捕获的位置。

正如我在评论中提到的,一个非常有趣的测试是这样的:

ArrayList<Tbin<? extends Base>> test3 = new TbinList<>();

我们得到这个错误:

error: incompatible types: cannot infer type arguments for TbinList<>
    ArrayList<Tbin<? extends Base>> test3 = new TbinList<>();
                                                        ^
    reason: no instance(s) of type variable(s) T exist so that
            TbinList<T> conforms to ArrayList<Tbin<? extends Base>>

所以没有办法让它按原样工作。其中一个类声明需要更改。


另外,这样想一下。

假设我们有:

class Derived1 extends Base {}
class Derived2 extends Base {}

由于通配符允许子类型化,我们可以这样做:

TbinList<? extends Base> test4 = new TbinList<Derived1>();

我们是否可以添加一个Tbin<Derived2> to test4?不,这将是堆污染。我们最终可能会得到Derived2s 漂浮在TbinList<Derived1>.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 泛型谜题,扩展类并使用通配符 的相关文章

随机推荐

  • Swift 将 AnyObject 转换为 Block

    因此 我使用 Salesforce SDK 并为整个 SDK 构建了桥接标头 它们提供了一个块语法 但尚未转换成最有用的代码 例如 func sendRESTRequest request SFRestRequest failBlock S
  • 在模板内对 $data 进行双向绑定

    我正在尝试设置通用的 Knockout 模板 可以根据数据类型在编辑和只读模式之间切换 如果您曾经使用过 ASP NET 的动态数据 它就像它们的字段模板 例如 这是这样使用的
  • 可以单独编译任何 .c 文件(即没有 main ?)

    我目前有一个 类似库 的 c 文件 如下所示 我有两个问题 如果我想看看它本身是否编译得很好 我该怎么做 如果我尝试 gcc 它 它总是会给出 no main 错误 这是有道理的 但会引发一个问题 知道给定的 c 文件是否可以在 隔离 中编
  • 迭代错误数组时出现 Swift 内存泄漏

    我对 Swift 比较陌生 所以我希望我没有问一个愚蠢的问题 我有一些实例化类型数组的代码Error 稍后将被迭代并打印到控制台 当使用 Leaks 工具通过 Instruments 运行此代码时 它显示了泄漏 SwiftNativeNSE
  • 如何使用jquery、express和handlebars创建无刷新页面?

    我正在学习 Express JS 我的问题是 我想使用 NodeJS 创建两个页面 它使用把手作为模板引擎 但我希望第一页应该使用发送res render home 第二个页面应该由 jQuery 使用 ajax 调用来调用 以表达并从表达
  • “错误:<路径> 属性 d:预期数字,“MNaN、NaNLNaN、NaNL…”。“ D3 错误

    我正在从 Quandl 的 API 导入一些数据 以制作多年来布伦特油价的图表 我正在提供来自 Angular 发出的 HTTP 请求的数据 不知何故 所提供的数据没有被读取为数字 因为我收到以下错误 错误 属性 d 预期数字 MNaN N
  • 设计 Vuetify 选择器的样式

    选择器的 Vuetify 组件是
  • TMonthCalendar 和 Delphi 样式 (Delphi XE2)

    TMontCalendar 似乎是一个 Windows 包装器 因此它不会受到新的 VCL 样式的影响 您知道解决方案吗 The TMonthCalendar http docwiki embarcadero com Libraries e
  • 当 Angular 完成向 DOM 添加范围更新时,如何触发方法?

    我正在寻找一种在向 scope 变量 在本例中为 scope results 添加更改后执行代码的方法 我需要这样做是为了调用一些遗留代码 这些代码要求项目位于 DOM 中才能执行 我的真实代码是触发 AJAX 调用 并更新作用域变量以更新
  • 如何使用 Sunspot 设置具有多对多关系的构面搜索?

    我之前没有实现过搜索功能 感觉有点卡住 我有一个太阳黑子搜索功能 可以根据关键字查找结果 这非常有效 但我现在想实现多选方面功能 但我什至不知道如何设置基本的方面搜索 我有多对多的关系 在 Rails 中而不是在现实生活中 类人 has m
  • 静态方法中的 Lock()

    我有一个多线程应用程序 它使用静态方法写入设置 xml 文件 我想避免文件同时更新两次 导致访问 写入异常 我怎么做 这不起作用 namespace Program public class Settings private static
  • DatePicker 未显示泰国文化的正确年份(2021 年应为 2564)

    我正在开发一个支持各种语言 文化的应用程序 但是 DatePicker 控件对于泰国文化来说似乎有问题 我尝试使用 ThreadCulture 也尝试过 CultureInfo CurrentCulture 或 CultureInfo Cu
  • C++11/14/17 Lambda 引用捕获 [&] 不复制 [*this]

    参考这个线程 https www open std org jtc1 sc22 wg21 docs papers 2018 p0806r2 html https www open std org jtc1 sc22 wg21 docs pa
  • System.getenv() 没有列出所有环境变量

    我注意到 JVM 没有获取我的一些环境变量 In my bash profile我定义了以下内容 IO HOME some value export IO HOME 并通过在 shell 中执行以下操作 echo IO HOME 我得到了正
  • Excel VBA,如何回复特定电子邮件

    我每个星期三都会收到来自特定发件人的邮件 此电子邮件的主题有时会发生变化 主题 暴露声明 COB 20150217 的示例 1 主题 保证金通知 COB 2015 Feb 10 的示例 2 发件人附加的日期是我收到邮件的前一天 我有以下代码
  • 具有固定标题的表格上的水平滚动

    我已经使用CSS创建了一个固定标题 主要只是设置要固定的标题位置 但是我遇到的问题是如果用户的分辨率大小或窗口大小小于表格大小 我需要添加在水平滚动条中 以便他们可以看到所有内容 我尝试将溢出设置为自动并滚动 但只有当我向下滚动到页面底部时
  • 如何加粗和更改图表标题的字体大小

    我可以动态创建箱线图 我现在面临的问题是我不知道如何bold并改变字体大小 of the 图表标题 我在网上研究了一段时间 但不知道如何做到这一点 这是我的代码 Chart Chart1 new Chart Chart1 DataSourc
  • CONTROL-C 之后 Django 服务器仍在运行

    我启动 Django 服务器python manage py runserver然后使用 CONTROL C 退出 但我仍然可以访问以下网址ROOT URLCONF why 可能您让另一个进程在其他地方运行 以下是列出命令包含的所有进程的方
  • string.replaceAll() 性能是否会受到字符串不变性的影响?

    假设我对一个大字符串调用了replaceAll 它替换了 1 000 个匹配实例 这是否意味着由于字符串不可变性 在进程中创建并重新分配了 1 000 个字符串 有没有更快的替代方案 如果你深入挖掘String http www docja
  • Java 泛型谜题,扩展类并使用通配符

    一段时间以来 我一直在努力解决这个问题 并认为也许一些新人会看到这个问题 谢谢你的时间 import java util class Tbin