小白日更第五十九天->语法糖吃过吗?

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。 来自百度百科

关于语法糖之前听过,但是没怎么深入的了解过。今天举几个简单,常用的例子。比如switch,增强for循环,if,数值字面量。下面我们一起来看一下。

第一块糖:switch

switch对于char, byte, short, int类型是本身就支持的,但其实它们都是转换成了整型,最后支持的其实是整型。但由于Java语法糖的出现,switch也支持String和enum类型了
原代码

public class SugarTest {
    public static void main(String[] args) {
        String str = "java";
        switch (str) {
            case "java":
                System.out.println("1");
                break;
            case "javac":
                System.out.println("2");
                break;
            default:
                System.out.println("default");
        }
    }
}

编译后代码

public class SugarTest {
    public SugarTest() {
    }

    public static void main(String[] args) {
        String str = "java";
        byte var3 = -1;
        switch(str.hashCode()) {
        case 3254818:
            if (str.equals("java")) {
                var3 = 0;
            }
            break;
        case 100899457:
            if (str.equals("javac")) {
                var3 = 1;
            }
        }

        switch(var3) {
        case 0:
            System.out.println("1");
            break;
        case 1:
            System.out.println("2");
            break;
        default:
            System.out.println("default");
        }

    }
}

可以看出,switch对于字符串类是比较字符串的hashcode方法以及通过equals方法确定是哪个字符串的,由于hashcode有一定概率会出现hash碰撞,用hashcode比较可能不太安全,所以仍需要进一步通过equals比较

第二块糖:自动拆装箱

自动拆装箱实际上是通过包装类的valueOf方法和xxxValue方法实现的,具体见我的一篇博客专门介绍自动拆装箱

第三块糖:for-each语法

增强for循环可谓是广泛使用,省去了去定义一个自增变量

public class SugarTest {
    public static void main(String[] args) {
        String[] strs = new String[]{"java", "python", "c++"};
        for (String str : strs) {
            System.out.println(str);
        }

        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            list.add(i);
        }

        for (Integer num : list) {
            System.out.println(num);
        }
    }
}

编译后代码

public class SugarTest {
    public SugarTest() {
    }

    public static void main(String[] args) {
        String[] strs = new String[]{"java", "python", "c++"};
        String[] var2 = strs;
        int i = strs.length;

        for(int var4 = 0; var4 < i; ++var4) {
            String str = var2[var4];
            System.out.println(str);
        }

        List list = new ArrayList();

        for(i = 0; i < 3; ++i) {
            list.add(i);
        }

        Iterator var7 = list.iterator();

        while(var7.hasNext()) {
            Integer num = (Integer)var7.next();
            System.out.println(num);
        }

    }
}

可以看出,一般的数组使用for-each背后的实现仅仅是把它变为普通fot循环而已,对于集合类使用for-each循环背后的实现是使用了Iterator遍历的

由于使用了迭代器Iterator,所以在数组遍历时不能修改数组(比如调用remove方法),否则根据fail-fast机制会抛出java.util.ConcurrentModificationException异常

第四块糖:方法变长参数

Java是允许将一种类型的任意数量的值作为参数使用的

public class SugarTest {
    public static void main(String[] args) {
        test("java", "python", "c++");
    }

    public static void test(String... strs) {
        for (String str : strs) {
            System.out.println(str);
        }
    }
}

编译后的代码

public class SugarTest {
    public SugarTest() {
    }

    public static void main(String[] args) {
        test("java", "python", "c++");
    }

    public static void test(String... strs) {
        String[] var1 = strs;
        int var2 = strs.length;

        for(int var3 = 0; var3 < var2; ++var3) {
            String str = var1[var3];
            System.out.println(str);
        }

    }
}

事实上就是将参数转变为了对应的数组

第五块糖:if条件编译

条件编译就是在编译期间编译器会选择有效的代码编译,不满足条件的代码称为无用代码,会被直接丢弃

public class SugarTest {
    private static final boolean DEBUG = true;

    public static void main(String[] args) {
        if (DEBUG) {
            System.out.println("DEBUG模式");
        } else {
            System.out.println("非DEBUG模式");
        }
    }
}

编译后的代码

public class SugarTest {
    private static final boolean DEBUG = true;

    public SugarTest() {
    }

    public static void main(String[] args) {
        System.out.println("DEBUG模式");
    }
}

上面的代码中编译器在编译时已经能确定只用执行DEBUG为true的代码,那么编译器只需要保存满足条件的一行代码即可,不需要全部保存

谈一谈条件编译的作用
有人会问了,既然DEBUG已知为true了,还去写个if多此一举干嘛,这其实是为了后期便于维护,就像上述代码一样,DEBUG模式可能是一段代码,非DEBUG模式可能是另外一段代码,开发者只需要改变常量DEBUG的值即可做到两种模式下的自由切换,岂不乐哉?这样配合编译器的条件编译机制又能使编译后的代码更为简洁,简直perfect!(通常这个常量可通过配置文件配置更为简便)

差不多我们平时写代码常用的就这些,具体可以参考这篇,我这篇博客也是转载这个大佬的。他还写了其他的语法糖,感兴趣的小伙伴可以去看一下。

其实就我而言可能面试官会问我是否了解java的语法糖,然后简单的举几个例子就可以,比如switch这个例子就很好,很好理解我们在写程序的时候也经常使用。
还有if,和数值字面量都可以说给面试官。但是我们面试的时候不可能把12条都说出来,把我们记住,理解的说出来就好了。但是我们平时自己学习还是多了解一下,对我们还是有好处的,不理解也没什么大问题,先记住有这么回事就可以了。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值