浅析java常见语法糖

本文深入浅出地介绍了Java中的语法糖,包括字符串拼接、条件编译、断言、枚举与Switch语句的结合、可变参数、自动装箱/拆箱等。通过反编译工具CFR的实例分析,揭示了这些语法糖在编译期间如何被解析和优化,以提升代码的可读性和效率。
摘要由CSDN通过智能技术生成

概念

1.语法糖Syntactic Sugar,也称糖衣语法,指计算机语言中添加某种语法,这种语法对语言的功能没有影响,但程序员使用更方便。在java中即JVM并不识别,会在编译器进行解析,还原成基础语法。
2.由com.sum.tools.javac.main.JavaCompiler中的deSugger方法,负责解析语法糖。

具体实现

java常见的语法糖包括:条件编译、断言、Switch语句与枚举及字符串结合、可变参数、自动装箱/拆箱、枚举、内部类、泛型擦除、增强for循环、lambda表达式、try-with-resources语句、JDK10的局部变量类型推断等等。

这里我借助另一个反编译工具 CFR 来分析java中的语法糖, 这里我下载的是最新的cfr_0_132.jar。

字符串拼接

        public void stringBuilderTest() {
        System.out.println("aa"+x+"bb"+"cc");
        System.out.println("aa"+"bb"+"cc");
        for(int i = 0; i < 1000; i++) {
            System.out.println("aa"+x+"bb"+"cc");
        }
    }

//    编译后
//    public void stringBuilderTest() {
//        System.out.println(new StringBuilder().append("aa").append(this.x).append("bbcc").toString());
//        System.out.println("aabbcc");
//        for (int i = 0; i < 1000; ++i) {
//            System.out.println(new StringBuilder().append("aa").append(this.x).append("bbcc").toString());
//        }
//    }

命令行: java -jar cfr-0.150.jar SyntacticSugar.class --stringbuilder false

1.从反编译后的代码中能看出, 当我们使用+号进行字符串拼接操作时, 编译时会自动创建一个StringBuilder对象。所以当在循环中拼接字符串时, 应避免使用+号操作, 否则每次循环都会创建一个StringBuilder对象再回收, 造成较大的开销。
2.可以看到对于字符串常量的拼接,在编译期就会自动拼接好,无需等待运行期。

条件编译

    public void ifCompilerTest() {
        if(true) {
            System.out.println("is True");
        }else {
            System.out.println("is False");
        }
    }

//    编译后
//    public void ifCompilerTest() {
//        System.out.println("is True");
//    }

命令行: java -jar cfr-0.150.jar SyntacticSugar.class

很明显, 编译器在编译时期的解语法糖阶段, 会将条件分支不成立的代码进行消除。

断言

    public void assertTest(String s) {
        assert (!s.equals("aaaa"));
        System.out.println(s);
    }
    
//    编译后
//    public void assertTest(String s) {
//        if (!$assertionsDisabled && s.equals("aaaa")) {
//            throw new AssertionError();
//        }
//        System.out.println(s);
//    }

命令行: java -jar cfr-0.150.jar SyntacticSugar.class --sugarasserts false

如上, 当断言结果为true时, 程序继续正常执行, 当断言结果为false时, 则抛出AssertionError异常来打断程序的执行。

枚举与Switch语句

    public enum EnumTest {
        FOO,
        BAR,
        BAP
    }

    public int switchEnumTest(EnumTest e) {
        switch (e) {
            case FOO:
                return 1;
            case BAP:
                return 2;
        }
        return 0;
    }
    
    //    编译后
//    public int switchEnumTest(EnumTest e) {
//        switch (1.$SwitchMap$com$qcloud$midware$hugo$syntactic$sugar$SyntacticSugar$EnumTest[e.ordinal()]) {
//            case 1: {
//                return 1;
//            }
//            case 2: {
//                return 2;
//            }
//        }
//        return 0;
//    }

命令行: java -jar cfr-0.150.jar SyntacticSugar.class --decodeenumswitch false

switch支持枚举是通过调用枚举类默认继承的父类Enum中的ordinal()方法来实现的, 这个方法会返回枚举常量的序数。

字符串与Switch语句

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值