Java数组与泛型

本贴最后更新于 3330 天前,其中的信息可能已经时异事殊

    是日快下班的时候,我到同事蕾丝大神座位上跟他唠嗑,他说问你个问题看你知道不。哥最近面试如流水,身经百战,自然胸有成竹地表示来来来。蕾丝问我:"为什么java的数组不支持泛型?"。擦,这货不按常理出牌呀。哥还真没有想过这问题,想了一会儿,回答他说:"是因为类型擦除吗?",他说他也不太清楚,但知道跟类型擦除有关。然后他打开IntelliJ写了以下例子:

public class GenericTest {
    private List<String> list1 = new ArrayList<String>();
    private List list2 = new ArrayList();
}


然后他用IntelliJ查看编译出来的字节码如下(我只节选重要部分):

   

public class GenericTest {
    // compiled from: GenericTest.java

   // access flags 0x2
   // signature Ljava/util/List&lt;Ljava/lang/String;&gt;;
   // declaration: java.util.List&lt;java.lang.String&gt;
   private Ljava/util/List; list1

   // access flags 0x2
   private Ljava/util/List; list2

   .....

}

他说从字节码可以看出编译之后泛型已经被擦除掉了。 他接着再写了以下例子:

 public class GenericTest {
/*    private List<String> list1 = new ArrayList<String>();
    private List list2 = new ArrayList();*/
private Integer[] integers = new Integer[]{};
private String[] strings = new String[]{};

}



编译后的字节码如下:
public class GenericTest {

// compiled from: GenericTest.java

// access flags 0x2
private [Ljava/lang/Integer; integers

// access flags 0x2
private [Ljava/lang/String; strings

 ....

}

可以看到对于数组而言,它作为一段连续的内存空间,在编译期间就必须知道它要存放的是哪一类的数据。最后,蕾丝大神表示要真正理解这个问题可能要去查阅一下java语言规范和java虚拟机规范的文档,他还提到一点就是数组是java一开山就存在的,那时还没有泛型这个概念,泛型是到java1.5后才有的,SUN为此还做了不少backward Compatible的工作。

说到这,虽然我还是有点疑问,但是对于蕾丝大神的研究精神甚是佩服。回家之后大概地做了一下总结。

说到泛型,当然首当其冲要说到类型擦除(Type Erasure),所谓的类型擦除,Java官方文档给出的说明如下:

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:

       1.Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
       2.Insert type casts if necessary to preserve type safety.
       3.Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.

加黑的第一点很重要,意思是说Java编译器将所有泛型类型参数(type parameters)替换成它们所绑定的类型,如果类型参数没有绑定,则替换成Object,这样编译出来的字节码,就会只包含了普通的类,接口和方法。这里所说的绑定(bound)是指像

public class Node<T extends Comparable<T>>


这样的,而没有绑定,则指像:
public class Node<T>


关于类型擦除,网上有篇文章(摸我)做了非常详细的说明,当然,Java官方文档也是必读的。而关于java数组为什么不支持泛型,我在网上搜了一圈,发现中文类的,只有这篇文章总结得较为靠谱。

 

 



  • Generic
    1 引用 • 1 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3190 引用 • 8214 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    前几个例子要是再加上赋值取值就更好了

推荐标签 标签

  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8447 引用 • 38484 回帖 • 155 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 49 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    288 引用 • 4485 回帖 • 663 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 548 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 172 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 672 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 15 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    171 引用 • 512 回帖
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 1 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    6 引用 • 63 回帖 • 5 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1795 回帖 • 1 关注
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    149 引用 • 257 回帖
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 592 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 318 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    288 引用 • 734 回帖 • 2 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    574 引用 • 3533 回帖
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    946 引用 • 943 回帖
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 104 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    343 引用 • 723 回帖
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 7 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    156 引用 • 3792 回帖
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 637 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 478 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 724 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 401 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖