2025-06-28 16:01

Java语法糖

码自答

Java后端

(13)

(0)

收藏

语法糖

Syntactic Sugar

在编程语言中添加一种新得语法,这种语法对语言本身得功能没有影响,可以更加方便程序员,代码更简洁。

Java 虚拟机并不支持语法糖,这些语法在编译阶段就会被还原成简单得基础语法结构。


Java 有哪些语法糖:

1    switch 支持 String 和枚举

Java 的 switch 本身只支持简单数据类型 int。其他数据类型都是转换成整型的。例如 byte、short 和 char。

字符串的 switch 是通过 equals 方法和 hashCode()方法实现的。显示通过 hashCode 方法获得哈希值比较,在通过 equals 方法进行安全检查


2    泛型

对于 Java 虚拟机而言,不能识别 Map<String,String>这样的语法,需要在编译阶段类型擦除。虚拟机中没有泛型,只有普通类和普通方法,所有范型类的类型参数在编译时都会被擦除。泛型类并没有自己独有的 Class 类对象。

ArrayList<String> list = new ArrayList<>()
String a = list.get(0);

编译之后

ArrayList list = new ArrayList();
String a = (String)list.get(0);


3    装箱和拆箱

装箱,Java 将基本数据类型转换成对应的包装类型。

Integer  a = 3;

编译之后

Integer a = Integer.valueOf(3);


拆箱,Java 将包装类类型转换成简单数据类型。

Integer a = new Integer(3);
int b = a;

编译之后

Integer a = new Integer(3);
int b = a.intValue();



4    可变长参数

可变长参数,编译之后就是一个数组

public static void main(String[] args)
{
    print(1,2,3,4,5);
}

public static void print(int ... args)
{
}

编译之后

public static void main(String[] args)
{
    print(new int[]{
        1,2,3,4,5
    });
}

public static void print(int[] args)
{
}


5    数字字面量

为了方便阅读,在数字中间添加下划线

int m = 10_000;

编译之后

int m = 10000;


6    枚举

枚举,Java 会创建一个继承自 Enum 的类,自动创建静态最终的对象

public enum Week{
    MONDAY,TUSDAY
}

反编译代码

public final class Week extends Enum{
    private Week(String s,int i){
        super(s,i);
    }
    ......
    public static final Week MONDAY;
    public static final Week TUSDAY;
    .....
}


7    内部类

内部类可以理解成外部类的一个普通成员。

某个类如果有内部类,那么在编译的时候,会生成两个 class 文件,外部类一个,内部类的 class 文件的文件名是 外部类名$内部类名.class.



8    断言

抛出 AssertionError 异常

int a = 1;
int b = 1;
assert a==b;

代码反编译

int a = 1;
int b = 1;
if(!$assertionDisabled && a!=b){
    throw new AssertionError();
}



9    条件编译

判断条件为常量的 if 语句实现,根据 if 判断条件的真假,编译器直接把分支为 else 的代码块消除。

boolean f1 = true;
boolean f2 = false;
if(f1){
    System.out.println("wanmait");
}
if(f2){
    System.out.println("万码学堂");
}

编译之后

boolean f1 = true;
boolean f2 = false;
System.out.println("wanmait");



10    lambda

lambda 表达式会生成一个方法,调用该方法

List<String> strList = ImmutableList.of("zhangsan","lisi","wangwu");
strList.forEach(s -> {Sustem.out.println(s)});

编译之后的代码

public static void main(String[] args) {
    ImmutableList strList = ImmutableList.of((Object)"zhangsan", (Object)"lisi", (Object)"wangwu");
    strList.forEach((Consumer<String>)LambdaMetafactory.metafactory(null, null, null, (Ljava/lang/Object;)V, lambda$main$0(java.lang.String ), (Ljava/lang/String;)V)());
}
//lambda生成的方法 
private static void lambda$main$0(String s) {
    System.out.println(s);
}



11    for-each 循环

public static void main(String[] args) {
    List<String> strList = ImmutableList.of("zhangsan", "lisi", "wangwu");
    for (String s : strList) {
        System.out.println(s);
    }
}

编译后代码为

public static transient void main(String args[])
{
    List strList = ImmutableList.of("zhangsan", "lisi", "wangwu");
    String s;
    for(Iterator iterator = strList.iterator(); iterator.hasNext(); System.out.println(s))
        s = (String)iterator.next();
 
}



12    try-with-resource

public static void main(String[] args) {
    try (BufferedReader br = new BufferedReader(new FileReader("file"))) {
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        // handle exception
    }
}

自动关闭 BufferedReader 流。


0条评论

点击登录参与评论