精华内容
下载资源
问答
  • 语法糖

    2020-12-22 13:40:53
    语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语。语 法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使 用。语法糖让...

    语法糖(Syntactic sugar,也译为糖衣语法,是由英国计算机科学家彼得·兰丁发明的一个术语。

    语 法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使 。语法糖让程序更加简洁,有更高的可读性。

    因为 Java 代码需要运行在 JVM 中,JVM 是并不支持语法糖的,语法糖在程序编译阶段就会被还原成简
    单的基础语法结构,这个过程就是 解语法糖
    下面看一下Java中的一些语法糖

    泛型与类型擦除

            在 JDK1.5 中,引入了泛型机制,但是泛型机制的本身是通过 类型擦除 来实现的,在 JVM 中没有泛型,
    泛型类的类型参数,在编译时都会被擦除。
    如在代码中定义的 List<Integer> List<String> 等类型,在编译之后都会变成ListJVM看到的只
    List,而由泛型附加的类型信息对JVM来说是不可见的。 因此,对于JVM来说, List<Integer>
    List<String> 就是同一个类,并不存在 List<String>.class 或是 List<Integer>.class ,而只有
    List.class ,所以,泛型实际上是Java语言的一个语法糖,又被叫做伪泛型
    比如例如,下面的代码输出结果为true
     
     
    List<Integer> List<String> 被认为是不同的类型,但是输出却得到了相同的结果,这是因为,
    泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型
    擦除。但是,如果将一个 Integer 类型的数据放入到 List<String> 中或者将一个 String 类型的数据放
    List<Integer> 中是不允许的。(不过当我们利用反射调用 add() 方法的时候, List<Integer>
    可以存储字符串,这说明了 Integer 泛型实例在编译之后被擦除掉了,只保留了原始类型。)
     

    增强for循环

    为什么有了普通的 for 循环后,还要有增强 for 循环呢?想一下,普通 for 循环需要知道遍历次数,每次
    还需要知道数组的索引是多少,这种写法明显有些繁琐。增强 for 循环与普通 for 循环相比,功能更强
    并且代码更加简洁,你无需知道遍历的次数和数组的索引即可进行遍历。但增强for循环并不能完全取代
    普通for循环。
    增强 for 循环的对象要么是一个数组,要么实现了 Iterable 接口。这个语法糖主要用来对数组或者集合
    进行遍历,其在循环过程中不能改变集合的大小。
     
     
     
     
     
    可以看出:
    数组形式的增强for循环退化为普通for循环,
    实现Iterable接口的增强for使用iterator接口进行遍历
    如上代码所示,如果对数组进行增强 for 循环的话,其内部还是对数组进行遍历,只不过语法糖把你忽悠
    了,让你以一种更简洁的方式编写代码。
    而对继承于 Iterator 迭代器进行增强 for 循环遍历的话,相当于是调用了 Iterator 的 hasNext()
    和 next() 方法。

     

    可变参数

    可变参数也叫变长参数,所谓变长参数,就是方法可以接受长度不定确定的参数。
     
     
     
     
    通过反编译可以得出的结论是可变参数其实就是使用了一个数组来接收。
     
     
     
     
    使用条件:一个方法只能有一个可变长参数,并且这个可变长参数必须是该方法的最后一个参数
     
     
     

    Switch 支持字符串

     

     

    switch 关键字原生只能支持 整数 类型。如果 switch 后面是 String 类型的话,编译器会将其转换成
    String hashCode 的值,所以其实 switch 语法比较的是 String hashCode
    如下代码所示
     
     
    根据字节码可以看到,进行 switch 的实际是 hashcode 进行判断,然后通过使用 equals 方法进行比
    较,因为字符串有可能会产生哈希冲突的现象。
     

    自动装箱与自动拆箱

     
    自动拆箱和自动装箱是一种语法糖,它说的是八种基本数据类型的包装类和其基本数据类型之间的自动
    转换。简单的说,装箱就是自动将基本数据类型转换为 包装 类型;拆箱就是自动将包装器类型转换为基
    本数据类型。
     
     
     
     
     
     
    装箱和拆箱的实现:
     
    public class Test01 { 
       public static void main(String[] args) { 
            Integer i = 10; // 自动装箱 
              int n = i; // 自动拆箱 
       } 
    }
    

     

     
    反编译后的结果
    public class Test01 { 
         public Test01() {}
          public static void main(String args[]) {
             Integer i = Integer.valueOf(10);
                int n = i.intValue(); 
    } 
    }
     
     
     
    从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是IntegervalueOf(int)方法。而在
    拆箱的时候自动调用的是IntegerintValue方法
     
     

    try-with-resources

    JDK 1.7 开始java引入了 try-with-resources 声明,将 try-catch-finally 简化为 try-catch,这其实是一
    语法糖 ,在编译时会进行转化为 try-catch-finally 语句。新的声明包含三部分:try-with-resources
    明、try 块、catch 块。它要求在 try-with-resources 声明中定义的变量实现了 AutoCloseable(自动关
    ) 接口,这样在系统可以自动调用它们的 close 方法,从而替代了 finally 中关闭资源的功能。
     
     
    public class Test {
       public static void main(String[] args) {
       try (FileInputStream fis = new FileInputStream(new
      File("C:\\Users\\86137\\Desktop\\6k.png"))){
       fis.read();
        } catch (Exception e) {
           e.printStackTrace();
         }
      }
    }

     

     
     
     
    经过反编译的结果
    public class Test {
       public Test() {
        }
       public static void main(String[] args) {
          try {
              FileInputStream fis = new FileInputStream(new
              File("C:\\Users\\86137\\Desktop\\6k.png"));
              Throwable var2 = null;
               try {
                  fis.read();
                } catch (Throwable var12) {
                     var2 = var12;
                      throw var12;
                } finally {
                    if (fis != null) {
                     if (var2 != null) {
                       try {
                            fis.close();
                       } catch (Throwable var11) {
                                 var2.addSuppressed(var11);
                       }
                     } else {
                           fis.close();
                      }
                }
               }
            } catch (Exception var14) {
               var14.printStackTrace();
            }
       }
    }

     

    可以看到,生成的 try-with-resources 经过编译后还是使用的 try…catch…finally 语句,只不过这部分工
    作由编译器替我们做了,这样能让我们的代码更加简洁,从而消除样板代码。
    语法糖还有许多,"字符串相加、枚举、断言、条件编译、lambda表达式"等等。。
     

    学习语法糖的好处

    需要声明的是语法糖这个词绝非贬义词,它可以给我们带来方便,是一种便捷的写法,编译器会帮我
    们做转换;而且可以提高开发编码的效率,在性能上也不会带来损失。
    很多编程思想,编程理论层出不穷,当然,对于学习来说我们是要抓住技术的核心,但对于工程来说如
    何提高工程质量,如何提高工程效率也是我们要关注的,既然这些语法糖能辅助我们以更好的方式编写
    代码为什么要抵制?
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,017
精华内容 4,006
关键字:

语法糖