Java ArrayList 实现中的类型擦除

2024-06-18

我正在阅读这篇文章Java 泛型 http://www.ibm.com/developerworks/library/j-jtp01255/index.html那里提到了一个构造函数ArrayList看起来有点像这样:

class ArrayList<V> {
  private V[] backingArray;
  public ArrayList() {
    backingArray = (V[]) new Object[DEFAULT_SIZE]; 
  }
}

我无法理解编译器的类型擦除和类型检查是如何发生的,如那里所解释的。我得到的一点是类型参数被转换为Object type.

我将其想象为(替换所有V with Object),但这绝对是错误的。

class ArrayList<Object> {
      private Object[] backingArray;
      public ArrayList() {
        backingArray = (Object[]) new Object[DEFAULT_SIZE]; 
      }
}

具体是如何转化为Object类型但仍保留类型安全V? 当我有ArrayList<String> and ArrayList<Integer>每个类别有两个不同的类别吗?如果没有的话,类型信息在哪里String and Integer被储存了?


您的类型擦除版本不正确。类型参数声明不会被删除Object但只有它的用法被删除。进一步来说:

  • 泛型类型的擦除是其对应的原始类型。因此对于ArrayList<V>,这只是ArrayList.
  • 类型参数的擦除是其最左边的边界。
  • 所有类型参数都被删除。类型参数是您在实例化泛型类时使用的参数。所以,ArrayList<Integer>将被替换为ArrayList.

所以,正确的擦除版本是:

class ArrayList {
    private Object[] backingArray;
    public ArrayList() {
      backingArray = (Object[]) new Object[DEFAULT_SIZE]; 
    }
}

当我有 ArrayList 和 ArrayList 时,每个都有两个不同的类吗?

不,事实并非如此。编译器仅生成泛型类型或方法的一种字节码表示形式,并将泛型类型或方法的所有实例化映射到唯一表示形式。

如果不是String和Integer的类型信息存储在哪里?

当编译器执行类型擦除时,它会根据一些预定义的规则删除所有类型信息,偶尔添加所谓的桥接法,并添加所需的所有必要类型转换。

因此,例如,以下用法ArrayList<Integer> and ArrayList<String>:

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
int value = list.get(0);

ArrayList<String> list2 = new ArrayList<String>();
list.add("A");
String value2 = list.get(0);

将被转换为类似这样的:

ArrayList list = new ArrayList();
list.add(1);
int value = (Integer) list.get(0);

ArrayList list2 = new ArrayList();
list.add("A");
String value2 = (String) list.get(0);

进一步阅读:

  • Java 泛型常见问题解答 - 什么是类型擦除? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20type%20erasure?
  • 为什么编译器在翻译泛型时要添加强制转换? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Why%20does%20the%20compiler%20add%20casts%20when%20it%20translates%20generics?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java ArrayList 实现中的类型擦除 的相关文章

随机推荐

  • 棋盘上骑士的最短路径

    我一直在为即将到来的编程比赛进行练习 我偶然发现了一个我完全困惑的问题 然而 我觉得这是一个我现在应该学习的概念 而不是祈祷它永远不会出现 基本上 它涉及棋盘上的骑士棋子 您将获得两个输入 起始位置和结束位置 目标是计算并打印骑士到达目标位
  • 使用 Beautifulsoup 抓取多个网站

    我想知道为什么列出all links and all titles不想接收列表中的任何记录titles and links 我也尝试过 extend 方法 但没有帮助 import requests from bs4 import Beau
  • 泛型和系统集合

    迁移到 NET 2 0 后 是否还有理由继续使用 systems Collections 命名空间 除了维护遗留代码之外 是否应该始终使用泛型命名空间 在大多数情况下 泛型集合的执行速度比非泛型集合更快 并且为您带来强类型集合的好处 比较
  • 挂钩 jQuery 验证消息更改

    我想在工具提示中显示 jQuery 验证消息 为了实现这一目标 我首先将以下 CSS 规则添加到我的样式表中 fieldset field validation error display none fieldset field valid
  • 使用通配符分割字符串

    我有一个变量字符串 其中包含我需要的值和拆分器 问题是 字符串的长度是可变的 分割器的类型也是可变的 它们通过 XML 文件到达 字符串将如下所示 1 20 51 2 name jpg 但也可以是 1 20 51 name jpg 坚实的因
  • 如何使用 Clang 编译器和 CMake 进行分析

    Question 1 What output我应该期待当我想使用进行分析时clang编译器 2 我该怎么办profiling for a C project它使用clang作为编译器andCMake 作为构建工具 重新分析我所使用的内容 1
  • cellForRowAtIndexPath 中的框架没有变化

    我想改变x位置框架view细胞内的cellForRowAtIndexPath对于某些条件 我使用了以下代码 但并不改变看法x position frame void viewDidLoad super viewDidLoad UINib n
  • Android WebView视频关闭全屏视图后,webview自动滚动

    我在用WebView显示包含文本和视频内容的网页 它按预期正确加载和显示视频 但是当我进入视频的全屏视图时 我按照给定的方式实现了全屏视频视图here https github com akhgupta WebviewVideo 然后回到W
  • Opencv C++ 检测并裁剪图像上的白色区域

    我在网上搜索过 已经找到了一些方法来完成我想要的事情 但是与我需要的相比 这些方法的效率较低 我有一个 kinect 使用 Microsoft SDK 当前正在获取一个移除背景的人 将结果保存在 3 通道 Mat 中 并将该人从背景中移除
  • Python,Pandas:每两行一起平均

    非常基本的问题 但想知道 在 pandas Dataframe 中对每 2 行进行平均的 正确 方法是什么 因此最终只有一半的行数 请注意 这与rolling mean 不同 因为它减少了条目数 一种快速的方法 gt gt gt s pd
  • 为什么 HTML5 DOCTYPE 会扰乱我的填充?

    我有一个带有导航栏的 html5 页面 完全从头开始编码 我最近刚刚向该项目添加了一个文档类型 现在我在导航栏下获得了额外的空间 如果我删除文档类型声明 它就会恢复正常 我已经完全重置了所有内容的填充 边距等 并将其缩减为说明问题的少量代码
  • 寻找两个框架之间的变换

    我有来自视频源的两个连续帧 并且我使用 FAST 算法检测这两个帧的关键点 我使用平方差之和法 SSD 来匹配关键点 所以基本上我已经匹配了两个框架之间的关键点 现在我想根据匹配的关键点集计算两个帧之间的仿射变换 缩放 旋转 平移 我知道如
  • 如何在表格单元格中插入输入字段?

    抱歉 新手问题 我想创建一个包含输入字段的表 如果需要 可以在其中添加新字段 但我不知道如何在已经存在另一个输入字段的单元格内添加另一个输入字段 我的代码是 var par obj parentNode while par nodeName
  • JavaScript 闭包

    我读到闭包末尾的 会立即执行它 那么 这两者有什么区别呢 我在一些代码中看到了第一个用法 thanks for var a selectsomeobj i 0 len a length i
  • 如何将 SPA 嵌入 ASP.NET Core 库并从路径提供服务

    Szenario 我想构建一个 aspnetcore 库 模块includes一个小的SPA前端 IE html js css 文件应与 dll 一起提供 SPA 应从特定路径提供服务 即 some module does not需要可配置
  • 再次返回使用 Rails 3 中的 Rails 2.3.5

    最近 我看到有关Rails 3 0 beta的信息 我想尝试一下 所以我使用gem update并安装了这个版本 但现在 我需要回到 Rails 2 3 5 我怎样才能做到呢 我正在考虑这两个解决方案 卸载 Rails 3 我读到有人使用
  • 在 IntelliJ 中运行 Spark 字数统计

    我花了几个小时浏览 You Tube 视频和教程 试图了解如何在 Scala 中运行 Spark 字数统计程序 并将其转换为 jar 文件 我现在完全糊涂了 我运行了 Hello World 并且了解了如何在 Apache spark sp
  • 使用不包含 Bloc 的上下文调用 BlocProvider.of() - 即使它包含

    首先 我确实知道 BLoC 是如何运作的 它背后的想法 我知道两者之间的区别BlocProvider and BlocProvider value 构造函数 为简单起见 我的应用程序有 3 个页面 其中有一个小部件树 如下所示 App gt
  • 如何在 WinRT XAML Toolkit 折线图中设置轴边距?

    Answer 最后我用这个解决了我的答案 LineSeries MyChart Series 0 IndependentAxis new LinearAxis Minimum 1 Maximum 5 Orientation AxisOrie
  • Java ArrayList 实现中的类型擦除

    我正在阅读这篇文章Java 泛型 http www ibm com developerworks library j jtp01255 index html那里提到了一个构造函数ArrayList看起来有点像这样 class ArrayLi