-
语法糖
2020-12-22 13:40:53语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语。语 法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使 用。语法糖让...语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语。
语 法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使 用。语法糖让程序更加简洁,有更高的可读性。
因为 Java 代码需要运行在 JVM 中,JVM 是并不支持语法糖的,语法糖在程序编译阶段就会被还原成简单的基础语法结构,这个过程就是 解语法糖 。下面看一下Java中的一些语法糖泛型与类型擦除
在 JDK1.5 中,引入了泛型机制,但是泛型机制的本身是通过 类型擦除 来实现的,在 JVM 中没有泛型,泛型类的类型参数,在编译时都会被擦除。如在代码中定义的 List<Integer> 和 List<String> 等类型,在编译之后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。 因此,对于JVM来说, List<Integer> 和List<String> 就是同一个类,并不存在 List<String>.class 或是 List<Integer>.class ,而只有List.class ,所以,泛型实际上是Java语言的一个语法糖,又被叫做伪泛型。比如例如,下面的代码输出结果为true。List<Integer> 和 List<String> 被认为是不同的类型,但是输出却得到了相同的结果,这是因为,泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。但是,如果将一个 Integer 类型的数据放入到 List<String> 中或者将一个 String 类型的数据放在 List<Integer> 中是不允许的。(不过当我们利用反射调用 add() 方法的时候, List<Integer> 却可以存储字符串,这说明了 Integer 泛型实例在编译之后被擦除掉了,只保留了原始类型。)增强for循环
为什么有了普通的 for 循环后,还要有增强 for 循环呢?想一下,普通 for 循环需要知道遍历次数,每次还需要知道数组的索引是多少,这种写法明显有些繁琐。增强 for 循环与普通 for 循环相比,功能更强并且代码更加简洁,你无需知道遍历的次数和数组的索引即可进行遍历。但增强for循环并不能完全取代普通for循环。增强 for 循环的对象要么是一个数组,要么实现了 Iterable 接口。这个语法糖主要用来对数组或者集合进行遍历,其在循环过程中不能改变集合的大小。可以看出:数组形式的增强for循环退化为普通for循环, 实现Iterable接口的增强for使用iterator接口进行遍历 如上代码所示,如果对数组进行增强 for 循环的话,其内部还是对数组进行遍历,只不过语法糖把你忽悠 了,让你以一种更简洁的方式编写代码。 而对继承于 Iterator 迭代器进行增强 for 循环遍历的话,相当于是调用了 Iterator 的 hasNext() 和 next() 方法。
可变参数
可变参数也叫变长参数,所谓变长参数,就是方法可以接受长度不定确定的参数。通过反编译可以得出的结论是可变参数其实就是使用了一个数组来接收。使用条件:一个方法只能有一个可变长参数,并且这个可变长参数必须是该方法的最后一个参数Switch 支持字符串
switch 关键字原生只能支持 整数 类型。如果 switch 后面是 String 类型的话,编译器会将其转换成String 的 hashCode 的值,所以其实 switch 语法比较的是 String 的 hashCode 。如下代码所示根据字节码可以看到,进行 switch 的实际是 hashcode 进行判断,然后通过使用 equals 方法进行比较,因为字符串有可能会产生哈希冲突的现象。自动装箱与自动拆箱
自动拆箱和自动装箱是一种语法糖,它说的是八种基本数据类型的包装类和其基本数据类型之间的自动转换。简单的说,装箱就是自动将基本数据类型转换为 包装 类型;拆箱就是自动将包装器类型转换为基本数据类型。装箱和拆箱的实现:public class Test01 { public static void main(String[] args) { Integer i = 10; // 自动装箱 int n = i; // 自动拆箱 } }
反编译后的结果public class Test01 { public Test01() {} public static void main(String args[]) { Integer i = Integer.valueOf(10); int n = i.intValue(); } }
从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。try-with-resources
JDK 1.7 开始,java引入了 try-with-resources 声明,将 try-catch-finally 简化为 try-catch,这其实是一种 语法糖 ,在编译时会进行转化为 try-catch-finally 语句。新的声明包含三部分:try-with-resources 声明、try 块、catch 块。它要求在 try-with-resources 声明中定义的变量实现了 AutoCloseable(自动关流) 接口,这样在系统可以自动调用它们的 close 方法,从而替代了 finally 中关闭资源的功能。public class Test { public static void main(String[] args) { try (FileInputStream fis = new FileInputStream(new File("C:\\Users\\86137\\Desktop\\6k.png"))){ fis.read(); } catch (Exception e) { e.printStackTrace(); } } }
经过反编译的结果public class Test { public Test() { } public static void main(String[] args) { try { FileInputStream fis = new FileInputStream(new File("C:\\Users\\86137\\Desktop\\6k.png")); Throwable var2 = null; try { fis.read(); } catch (Throwable var12) { var2 = var12; throw var12; } finally { if (fis != null) { if (var2 != null) { try { fis.close(); } catch (Throwable var11) { var2.addSuppressed(var11); } } else { fis.close(); } } } } catch (Exception var14) { var14.printStackTrace(); } } }
可以看到,生成的 try-with-resources 经过编译后还是使用的 try…catch…finally 语句,只不过这部分工作由编译器替我们做了,这样能让我们的代码更加简洁,从而消除样板代码。语法糖还有许多,如"字符串相加、枚举、断言、条件编译、lambda表达式"等等。。学习语法糖的好处
需要声明的是“语法糖”这个词绝非贬义词,它可以给我们带来方便,是一种便捷的写法,编译器会帮我们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。很多编程思想,编程理论层出不穷,当然,对于学习来说我们是要抓住技术的核心,但对于工程来说如何提高工程质量,如何提高工程效率也是我们要关注的,既然这些语法糖能辅助我们以更好的方式编写代码为什么要“抵制“呢?
收藏数
10,017
精华内容
4,006
-
JAVA设计模式之装饰者模式
-
基于显著算法与CIELAB空间的织物色差评价方法
-
github下载提速常用方法
-
DW&LeetCode_day15(231、235、236)
-
易语言开发通达信DLL公式接口
-
荧光显微成像用于研究卵母细胞减数分裂过程
-
Qt and Qt Charts
-
【数据分析实战训练营】Hive详解
-
Appium自动化测试套餐
-
面试题:递归实现阶乘【Java初级-北京】
-
融合彩色不变量和SURB检测的特征点匹配算法
-
JDBC工具类——JdbcUtils(5)
-
取石子游戏(威佐夫博弈)
-
运放的带宽(一)
-
基于SSM的小区报修系统
-
javaweb仓库出入库系统 毕业设计 毕设 源代码 使用教程
-
JAVAEE主流框架之Spring框架实战开发教程(源码+讲义)
-
gbkeegbaiigmenfmjfclcdgdpimamgkj-135.360.369-Crx4Chrome.com.crx
-
LIS与HIS系统接口规范说明.pdf
-
Zookeeper 1