65.Java语法糖

语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。Java 中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等。虚拟机并不支持这些语法,它们在编译阶段就被还原回了简单的基础语法结构,这个过程成为解语法糖。

泛型是 JDK1.5 之后引入的一项新特性,Java 语言在还没有出现泛型时,只能通过 Object 是所有类型的父类和类型强制转换这两个特点的配合来实现泛型的功能,这样实现的泛型功能要在程序运行期才能知道 Object 真正的对象类型,在 javac 编译期,编译器无法检查这个 Object 的强制转型是否成功,这便将一些风险转接到了程序运行期中。

Java 语言在 JDK1.5 之后引入的泛型实际上只在程序源码中存在,在编译后的字节码文件中,就已经被替换为了原来的原生类型,并且在相应的地方插入了强制转型代码,因此对于运行期的Java语言来说,ArrayList和 ArrayList就是同一个类。所以泛型技术实际上是 Java 语言的一颗语法糖,Java 语言中的泛型实现方法称为类型擦除,基于这种方法实现的泛型被称为伪泛型。

下面是一段简单的 Java 泛型代码:

Map<Integer,String> map = new HashMap<Integer,String>();
map.put(1,"No.1");
map.put(2,"No.2");
System.out.println(map.get(1));
System.out.println(map.get(2));

将这段 Java 代码编译成 Class 文件,然后再用字节码反编译工具进行反编译后,将会发现泛型都变回了原生类型,如下面的代码所示:

Map map = new HashMap();
map.put(1,"No.1");
map.put(2,"No.2");
System.out.println((String)map.get(1));
System.out.println((String)map.get(2));

为了更详细地说明类型擦除,再看如下代码:

import java.util.List;
public class FanxingTest{  public void method(List<String> list){  System.out.println("List String");  }  public void method(List<Integer> list){  System.out.println("List Int");  }
}

当用 javac 编译器编译这段代码时,报出了如下错误:

FanxingTest.java:3: 名称冲突:method(java.util.List<java.lang.String>) 和 method(java.util.List<java.lang.Integer>) 具有相同疑符public void method(List<String> list){^FanxingTest.java:6: 名称冲突:method(java.util.List<java.lang.Integer>) 和 method(java.util.List<java.lang.String>) 具有相同疑符public void method(List<Integer> list){^

2 错误
是因为泛型 List 和 List 编译后都被擦除了,变成了一样的原生类型 List,擦除动作导致这两个方法的特征签名变得一模一样,在 Class 类文件结构一文中讲过,Class 文件中不能存在特征签名相同的方法。
把以上代码修改如下:

import java.util.List;
public class FanxingTest{  public int method(List<String> list){  System.out.println("List String");  return 1;  }  public boolean method(List<Integer> list){  System.out.println("List Int");  return true;  }
}

发现这时编译可以通过了(注意:Java 语言中 true 和 1 没有关联,二者属于不同的类型,不能相互转换,不存在 C 语言中整数值非零即真的情况)。两个不同类型的返回值的加入,使得方法的重载成功了。这是为什么呢?

我们知道,Java 代码中的方法特征签名只包括了方法名称、参数顺序和参数类型,并不包括方法的返回值,因此方法的返回值并不参与重载方法的选择,这样看来为重载方法加入返回值貌似是多余的。对于重载方法的选择来说,这确实是多余的,但我们现在要解决的问题是让上述代码能通过编译,让两个重载方法能够合理地共存于同一个 Class 文件之中,这就要看字节码的方法特征签名,它不仅包括了 Java 代码中方法特征签名中所包含的那些信息,还包括方法返回值及受查异常表。为两个重载方法加入不同的返回值后,因为有了不同的字节码特征签名,它们便可以共存于一个 Class 文件之中。

自动拆装箱、变长参数等语法糖也都是在编译阶段就把它们该语法糖结构还原为了原生的语法结构,因此在 Class 文件中也只存在其对应的原生类型,这里不再一一说明。

65.Java语法糖相关推荐

  1. Java 语法糖详解

    语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序 ...

  2. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

  3. java语法糖效率高吗_打包 Java将持续向“高糖”方向发展,你真的了解Java语法糖吗? _好机友...

    Java语法糖概念 1. 语法糖Syntactic Sugar 糖衣语法,方便开发人员使用,JVM并不识别,会在编译阶段解语法糖,还原为基础语法. 2. com.sun.tools.javac.mai ...

  4. JAVA语法糖(全)

    JAVA语法糖(全) 目录 概述 字符串拼接 条件编译 断言 枚举与Switch语句 字符串与Switch语句 可变参数 自动装箱/拆箱 枚举 内部类 泛型擦除 增强for循环 lambda表达式 t ...

  5. Jvm 系列(十一)Java 语法糖背后的真相

    语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言 ...

  6. Java语法糖之foreach

    语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用了.这些语 ...

  7. Java中switch参数传null会引起异常——Java 语法糖

    问题 switch 参数不能是null,swicth(null)会报java.lang.NullPointerException异常 查找原因 为什么会这样呢,查找一下原因: 找到编译后的class文 ...

  8. c++接口调用外部类_Java基础:Java语法糖4之内部类

    内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...

  9. java 语法糖 字符串,java中的一些语法糖

    Java中的语法糖 语法糖的定义:语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,并没有给语言添加什么新东西,但是更方便程序员使用.通常来说使用语法糖能够增加程序的可读性,从而减少 ...

最新文章

  1. eShopOnContainers 知多少[8]:Ordering microservice
  2. C# 向TIM或者QQ自动发送中文消息【微信也是可用的】 附测试GIF
  3. CSP认证201409-3 字符串匹配[C++题解]:字符串处理
  4. python逐行读取文件内容的三种方法
  5. Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)
  6. JavaOne正在重建动力
  7. 程序猿们,如果你不想跑偏,就千万别读这4本书!
  8. matlab 中pid tuning,PID Tuning Algorithm
  9. windows下安装pycharm并连接Linux的python环境
  10. windows下双击可运行的Java软件打包方案
  11. CSDN账号注册 设置用户名
  12. 网闸端口限制时,用HaneWin NFS Server来部署单一接口来交互,实现挂载便于访问
  13. 2022身份识别技术大会 | 安全证件 | 可信身份认证 | 生物识别 | 公共安全安防身份技术展览会
  14. 用AI对抗AI!教代码调戏深度学习算法生成的假视频
  15. 数据结构与算法分析:实现list【理解 iter++ 和 ++iter 】
  16. postman不能启动的问题解决
  17. Python字符串底层原理
  18. 代码详细教程+文档+PPT+源码等]SSM框架美妆商城全套|电商购物计算机专业毕业论文java毕业设计网站
  19. 利用ECharts可视化mysql数据库中的数据
  20. 【机器学习课程-华盛顿大学】:4 聚类和检索 4.4 MoG混合高斯模型编程测试

热门文章

  1. 《推荐系统实践》附上Reference 中的干货 (Paper,Blog等资料的链接)
  2. 多目标遗传优化算法nsga2求解复杂约束问题【python源码实现,二进制编码】
  3. 给书配代码-电力经济调度(1):基于拉格朗日及运筹规划方法的经济调度算法
  4. opengl加载显示3D模型HMP类型文件
  5. wxWidgets:wxToolBar 示例
  6. wxWidgets:添加控件
  7. wxWidgets:文件类和函数
  8. boost::mpl::remove相关的测试程序
  9. boost::math::statistics相关用法的测试程序
  10. ITK:二进制图像的近似距离图