Java开发工程师进阶篇 - Java中隐藏的一些语法糖,你zao吗?

语法糖(Syntactic Sugar),也称糖衣语法,出自英国计算机学家 Peter.J.Landin 发明的一个术语,指的是在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。

本文通过实例代码,学习理解 Java 中的语法糖原理及用法,帮助大家在学会如何使用 Java 语法糖的同时,了解这些语法糖背后的原理。

自动装箱与拆箱

  • 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。
  • 如果装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte, short, char, int, long, float, double 和 boolean 对应的封装类为Byte, Short, Character, Integer, Long, Float, Double, Boolean。
  • 代码实例:
    • 自动装箱
      • // 编译前
        int a = 8;
        Integer b = a;
        
        // 编译后
        int a = 8;
        Integer b = Integer.valueOf(a);
        
    • 自动拆箱
      • // 编译前
        Integer a = 8;
        int b = a;
        
        // 编译后
        Integer a = Integer.valueOf(8);
        int b = a.intValue();
        
  • 从反编译得到内容可以看出,在装箱的时候自动调用的是IntegervalueOf(int)方法。而在拆箱的时候自动调用的是IntegerintValue方法。
  • 装箱过程是通过调用包装器的 valueOf 方法实现的,而拆箱过程是通过调用包装器的 intValue 方法实现的。

数值字面量

  • 从Java7 开始,数值字面量,不管是整数还是浮点数,都允许在数字之间插入任意多个下划线。这些下划线不会对字面量的数值产生影响,目的就是方便阅读。
  • 代码实例:
    • // 编译前
      int a = 520_1314;
      System.out.println(a);
      
      // 编译后
      int a = 5201314;
      System.out.println(a);
      
  • 从示例代码中,可以发现反编译后就是把_删除了。说明编译器并不认识在数字字面量中的 _,在编译阶段把他去掉。
  • 在开发中,如果输入的数字值太长,可以加以分割提高可读性。

字符串拼接

  • 字符串+号拼接原理是两个字符串的拼接首先会new一个StringBuilder对象,然后分别对字符串进行append操作,最后调用toString()方法。
    • 代码实例:
      • // 编译前
        String a = "hello";
        String b = "world";
        String c = a + b;
        
        // 编译后
        String a = "hello";
        String b = "world";
        String c = (new StringBuilder()).append(a).append(b).toString();
        
  • 如果在多个字符串拼接的场景,推荐直接使用StringBuilder效率会更加的高,使用+会创建多个StringBuilder对象,导致效率降低。

断言

  • 在Java中,assert关键字是从JAVA SE 1.4 引入的,为了避免和老版本的Java代码中使用了assert关键字导致错误,Java在执行的时候默认是不启动断言检查的(这个时候,所有的断言语句都将忽略!),如果要开启断言检查,则需要用开关-enableassertions-ea来开启。
  • 代码实例:
    • // 编译前
      int a = 5;
      int b = 6;
      assert a == b;
      System.out.println("断言正确!");
      
      // 编译后
      int a = 5;
      int b = 6;
      if(!$assertionsDisabled && a != b)
           throw new AssertionError();
      System.out.println("断言正确!");
      
  • 编译之后的代码要比我们写的代码复杂的多。所以,使用了assert这个语法糖我们节省了很多代码。
  • 其实断言的底层实现就是if语言,如果断言结果为true,则什么都不做,程序继续执行,如果断言结果为false,则程序抛出 AssertError 来打断程序的执行。
  • 断言一般在开发中使用的较少,但需要我们了解 Java 中有这个机制。

方法参数可变

  • 可变参数(variable arguments)是在Java 1.5中引入的一个特性,允许一个方法中传入可变数量的相同类型参数。
  • 代码实例
    • public void varParam(String... ls) {
          for(int i = 0; i < ls.length; ++i) {
              System.out.println(ls[i]);
          }
      }
      
  • 可变参数在被使用的时候,首先会创建一个数组,数组的长度就是调用该方法是传递的实参的个数,然后再把参数值全部放到这个数组当中,然后再把这个数组作为参数传递到被调用的方法中。

Lambda表达式

  • lambda表达式允许你通过表达式来代替功能接口。Lambda表达式还增强了集合库。
  • Java SE 8添加了2个对集合数据进行批量操作的包:java.util.function 包以及java.util.stream 包。
  • 流(stream)就如同迭代器(iterator),但附加了许多额外的功能。 总的来说,lambda表达式和 stream 是自Java语言添加泛型(Generics)和注解(annotation)以来最大的变化。
  • 代码实例:
    • Runnable runnable = () -> {
          System.out.println("l am a new thread...");
      };
      new Thread(runnable).start();
      
  • lambda表达式的实现其实是依赖了一些底层的api,在编译阶段,编译器会把lambda表达式进行解糖,转换成调用内部api的方式。

总结

  • 所谓语法糖就是提供给开发人员便于开发的一种语法而已,有了这些语法糖,我们在日常开发的时候可以大大提升效率,但是同时也要避免过渡使用。使用之前最好了解下原理,避免掉坑。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值