15 | Java语法糖与Java编译器
郑雨迪
该思维导图由 AI 生成,仅供参考
在前面的篇章中,我们多次提到了 Java 语法和 Java 字节码的差异之处。这些差异之处都是通过 Java 编译器来协调的。今天我们便来列举一下 Java 编译器的协调工作。
自动装箱与自动拆箱
首先要提到的便是 Java 的自动装箱(auto-boxing)和自动拆箱(auto-unboxing)。
我们知道,Java 语言拥有 8 个基本类型,每个基本类型都有对应的包装(wrapper)类型。
之所以需要包装类型,是因为许多 Java 核心类库的 API 都是面向对象的。举个例子,Java 核心类库中的容器类,就只支持引用类型。
当需要一个能够存储数值的容器类时,我们往往定义一个存储包装类对象的容器。
对于基本类型的数值来说,我们需要先将其转换为对应的包装类,再存入容器之中。在 Java 程序中,这个转换可以是显式,也可以是隐式的,后者正是 Java 中的自动装箱。
以上图中的 Java 代码为例。我构造了一个 Integer 类型的 ArrayList,并且向其中添加一个 int 值 0。然后,我会获取该 ArrayList 的第 0 个元素,并作为 int 值返回给调用者。这段代码对应的 Java 字节码如下所示:
当向泛型参数为 Integer 的 ArrayList 添加 int 值时,便需要用到自动装箱了。在上面字节码偏移量为 10 的指令中,我们调用了 Integer.valueOf 方法,将 int 类型的值转换为 Integer 类型,再存储至容器类中。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入讨论了Java编译器的协调工作和语法特性,重点探讨了自动装箱和自动拆箱、泛型与类型擦除以及桥接方法。自动装箱和自动拆箱是Java编译器在处理基本类型和包装类型转换时的协调工作,而泛型的类型擦除则是为了兼容引入泛型之前的代码。此外,文章还详细解释了桥接方法在Java字节码层面重写父类方法的作用。另外,还介绍了foreach循环和字符串switch的编译处理。读者可以通过本文更好地理解Java语言的底层实现和特性。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Java 虚拟机》,新⼈⾸单¥59
《深入拆解 Java 虚拟机》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(20)
- 最新
- 精选
- 钱本节还是比较容易理解的,也搞清楚了泛型相关的疑惑点,非常感谢。 小结如下: 1:Java语法糖-是一种帮助开发人员提高开发效率的小甜点,原理是将一些繁琐的事情交给编译器来处理,开发人员少做一些事情,当然,本纸上这些事情还必须要做,只是有编译器来做了 2:Java语法糖有那几种呢?如下所示: 2-1:包装类型和基本类型间的转换,自动装箱和拆箱的设计 2-2:泛型的设计 2-3:变长参数的设计 2-4:try-with-resources,关闭资源的设计 2-5:在同一个catch代码块中捕获多种异常 2-6:finally代码块总是被执行的设计 2-7:foreach循环数组的设计 2-8:foreach循环Iterable对象的设计 3:编译器的具体实现细节不是很清楚,猜测是识别出对应的语法然后填充上对应的代码,将语法糖还原成其本质-一些重复繁琐的代码块 4:之前有同事问我泛型是怎么实现的? 我讲不出来,只晓得使用泛型后,不需要写类型强转的代码了,如果类型不对也会有提示且编译失败,现在知道的多一点了,本质上类型强转的工作还是必须要做的,只是不是有开发人员来做了,由编译器来做,并且编译器会擦除掉对应的泛型信息,使用合适的父类型来代替,可能是Object类也可能是声明泛型时指定的继承的类
作者回复: 赞
2018-08-2560 - ^_^C++ 是真泛型,java 较之算是伪泛型
作者回复: 确实
2018-11-1339 - Shine每次看到示例代码的java字节码就犯懵,觉得很复杂,是不是有必要去了解下字节码
作者回复: 字节码其实不难的。我会专门写一篇来介绍一下。
2018-08-256 - 任鹏斌有点落后刚升级到jdk8对10还一无所知
作者回复: Java新版本的语法糖并不多,我印象中10也只有var
2018-08-242 - 李二木从实现上说可以设计一个int类型的list,而jdk中arrayList是object类型,这样做是不是为了通用型考虑呢?
作者回复: 对的
2018-08-2422 - 403相比来看,c#的泛型是真泛型
作者回复: ;)
2018-08-26 - herome求老师画图啊
作者回复: 这一篇貌似没啥地方能够画图的吧?请问你具体对哪一块有疑问?
2018-08-25 - 钱奇怪的是,Java 并不支持对 IntegerCache.low 的更改,也就是说,对于小于 -128 的整数,我们无法直接使用由 Java 核心类库所缓存的 Integer 对象。 这个奇怪的现象到底是为啥呢?
作者回复: JDK认为用户不需要缓存小于-128的整数。这当然有可能是错误的。
2018-08-25 - 永烁星光直到这节课逐渐感知到了学习jvm的妙处,我想将这专栏反复看和实践终能消化为自己的知识2018-08-2518
- 曲东方var保存了泛型信息 var定义变量必须直接初始化,基于初始化的值做类型推导,javac编译期间的语法糖 所以不能声明函数的参数为var类型 foreach语法糖,对于实现了迭代器Iterable<T>接口的类型,使用迭代器方法; foreach对于数组和变长参数的处理方式与上述略有不同,先求数组长度,再做类似while循环遍历2018-08-2615
收起评论