Java数组与泛型

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

    是日快下班的时候,我到同事蕾丝大神座位上跟他唠嗑,他说问你个问题看你知道不。哥最近面试如流水,身经百战,自然胸有成竹地表示来来来。蕾丝问我:"为什么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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖 • 1 关注

相关帖子

欢迎来到这里!

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

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

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

推荐标签 标签

  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 18 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 223 关注
  • Linux

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

    939 引用 • 940 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 31 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 294 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    19 引用 • 31 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    28 引用 • 108 回帖
  • WiFiDog

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

    1 引用 • 7 回帖 • 586 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 53 关注
  • Mobi.css

    Mobi.css is a lightweight, flexible CSS framework that focus on mobile.

    1 引用 • 6 回帖 • 733 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    124 引用 • 580 回帖
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    90 引用 • 899 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 60 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 632 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖 • 2 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    54 引用 • 292 回帖
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    22019 引用 • 87804 回帖 • 2 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • 创业

    你比 99% 的人都优秀么?

    84 引用 • 1399 回帖 • 1 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 621 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 366 关注
  • OnlyOffice
    4 引用 • 2 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 19 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 911 回帖 • 237 关注