语法糖(Syntactic Sugar),也称糖衣语法,指在计算机语言中添加的某种语法,这种语法对语言本身的功能来说没有什么影响,只是为了方便程序员进行开发,提高开发效率,使用这种语法写出来的程序可读性也更高。说白了,语法糖就是对现有语法的一个封装。

但其实,Java虚拟机是并不支持语法糖的,语法糖在程序编译阶段就会被还原成简单的基础语法结构,这个过程就是解语法糖。所以在Java中真正支持语法糖的是Java编译器。


Java中的语法糖#

Java编程语言提供了很多语法糖,整理了下,主要有下面几种常用的语法糖。

  • switch-case对String和枚举类的支持
  • 泛型
  • 包装类自动装箱与拆箱
  • 方法变长参数
  • 枚举
  • 内部类
  • 条件编译
  • 断言
  • 数值字面量
  • 增强for循环
  • try-with-resource语法
  • Lambda表达式
  • 字符串+号语法

switch对String和枚举类的支持#

switch对枚举和String的支持原理其实是差不多的。下面以String为列子介绍下具体的原理。

switch关键字原生只能支持整数类型。如果switch后面是String类型的话,编译器会将其转换成String的hashCode的值,所以其实switch-case语法比较的是String的hashCode值。

如果switch后面是Enum类型的话,编译器会将其转换为这个枚举定义的下标(ordinal)。其实最后都是比较的整数类型。下面以Stirng举个列子。

源代码

Copy
public class SwitchDemoString { public static void main(String[] args) { String str = "world"; switch (str) { case "hello": System.out.println("hello"); break; case "world": System.out.println("world"); break; default: break; } } }

反编译后的代码

Copy
public class SwitchDemoString { public switchDemoString() { } public static void main(String args[]) { String str = "world"; String s; switch((s = str).hashCode()) { default: break; case 99162322: //这边需要再次通过equals方法进行判断,因为不同字符串的hashCode值是可能相同的,比如“Aa”和“BB”的hashCode就是一样的 if(s.equals("hello")) System.out.println("hello"); break; case 113318802: if(s.equals("world")) System.out.println("world"); break; } } }

通过反编译可以发现,进行switch的实际是哈希值,然后通过使用equals方法比较进行安全检查,这个检查是必要的,因为哈希可能会发生碰撞。因此它的性能是不如使用枚举进行switch或者使用纯整数常量。

PS:这边顺带简单介绍一个Java的反编译软件Jad。下载地址的话大家可以在网上找下。使用起来非常简单:

Copy
jad -p SwitchDemoString.class > SwitchDemoString.java

上面的命令就可以将class文件反编译成Java文件。这个只是