Java中的语法糖(🧋真甜)

12,107 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

什么是语法糖(Syntactic sugar)

语法糖是一个计算机数据,特指在编程语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。

糖嘛,对应的词汇就是甜。而语法糖就是让你的代码更甜🐶。

实际上就像上面介绍的,如果可以将语句中的一些构造从语句中删除而不影响语言的功能,那么它就是语法糖。

Java中常见的语法糖

复合赋值运算符是赋值运算符的语法糖

x += 1 对应 x = x + 1 
x -= 1 对应 x = x - 1

递增/递减运算符是复合赋值运算符的语法糖

x++ 代替 x += 1 
x-- 代替 x -= 1

三元运算符是If-then-else语句的语法糖

(条件?满足:否则)

增强型 For 循环是 For 循环的语法糖,带有一个迭代器

for (String str:arrayList) {
  
}

上面的增强for循环是下面带有迭代器的 for 循环的语法糖

for (Iterator<String> it = arrayList.iterator(); it.hasNext();) {
  String str = it.next();
  // Implementation logic
}

划重点

去糖化

语言处理器,包括编译器和静态分析器,通常在处理之前将糖化结构扩展为更基本的结构,这个过程有时称为“去糖化”。例如,增强的 for 循环将在编译时被取消为带有迭代器的 for 循环。

语法糖和运行时异常

重要的是要了解糖化和去糖化,因为糖化结构会根据其去糖化结构引发某些运行时异常。

举个例子:

大家都知道不能在增强for循环中进行集合的增删操作,否则会抛异常。

是因为增强的 For 循环在迭代Collection 时,使用Collection remove()方法从 Collection 中删除元素时抛出java.util.ConcurrentModificationException 。

虽然在迭代集合时从集合中移除元素(使用集合 remove() 方法)时,带有计数器的通用 for 循环不会抛出java.util.ConcurrentModificationException 。

这是因为在编译时,增强的 for 循环被去糖化,转换成具有Fail-fast 迭代器的通用 for 循环。

Fail-fast 迭代器在迭代Collection 时从 Collection 中移除元素(使用Collection remove() 方法)时抛出java.util.ConcurrentModificationException。

再聊点有趣的:语法盐(syntactic salt)

语法盐是指为了降低开发者写出不良代码的设计。举个简单例子,在C语言和C++的Switch中,如果case语句不加break,编译器并不会产生错误信息。还有一些程序员认为定义变量类型也是语法盐的一种。

再举个例子,在Java当中,不允许将float类型的变量赋值给定义为int类型的变量,但是在C或者C++当中,会自动把float类型的变量舍去小数并赋值给int类型的变量。

int num1;
float pi=3.14159;
num1=pi;  //賦值錯誤

语法盐有可能会违背它的初衷,使代码的可读性降低或浪费代码的空间占用。在极端条件下,真正有用的代码可能要比为了满足语法盐要求而增加的代码还要短。

另外一种替代语法盐的方法是在代码可能产生错误时,让编译器产生警告——这也是C和C++的编译器常见的作法。