<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 中的 6 顆語(yǔ)法糖

          共 4733字,需瀏覽 10分鐘

           ·

          2020-10-16 00:05

          作者:Java 技術(shù)棧
          來源:SegmentFault 思否社區(qū)




          原文作者:danchu
          原文鏈接:
          https://blog.csdn.net/danchu/article/details/54986442

          語(yǔ)法糖(Syntactic Sugar),也稱糖衣語(yǔ)法,指在計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,這種語(yǔ)法對(duì)語(yǔ)言本身功能來說沒有什么影響,只是為了方便程序員的開發(fā),提高開發(fā)效率。說白了,語(yǔ)法糖就是對(duì)現(xiàn)有語(yǔ)法的一個(gè)封裝。

          Java作為一種與平臺(tái)無(wú)關(guān)的高級(jí)語(yǔ)言,當(dāng)然也含有語(yǔ)法糖,這些語(yǔ)法糖并不被虛擬機(jī)所支持,在編譯成字節(jié)碼階段就自動(dòng)轉(zhuǎn)換成簡(jiǎn)單常用語(yǔ)法。

          一般來說Java中的語(yǔ)法糖主要有以下幾種:

          1. 泛型與類型擦除
          2. 自動(dòng)裝箱與拆箱
          3. 變長(zhǎng)參數(shù)
          4. 增強(qiáng)for循環(huán)
          5. 內(nèi)部類
          6. 枚舉類




          泛型與類型擦除

          Java語(yǔ)言并不是一開始就支持泛型的。在早期的JDK中,只能通過Object類是所有類型的父類和強(qiáng)制類型轉(zhuǎn)換來實(shí)現(xiàn)泛型的功能。強(qiáng)制類型轉(zhuǎn)換的缺點(diǎn)就是把編譯期間的問題延遲到運(yùn)行時(shí),JVM并不能為我們提供編譯期間的檢查。

          在JDK1.5中,Java語(yǔ)言引入了泛型機(jī)制。但是這種泛型機(jī)制是通過類型擦除來實(shí)現(xiàn)的,即Java中的泛型只在程序源代碼中有效(源代碼階段提供類型檢查),在編譯后的字節(jié)碼中自動(dòng)用強(qiáng)制類型轉(zhuǎn)換進(jìn)行替代。也就是說,Java語(yǔ)言中的泛型機(jī)制其實(shí)就是一顆語(yǔ)法糖,相較與C++、C#相比,其泛型實(shí)現(xiàn)實(shí)在是不那么優(yōu)雅。

          /*** 在源代碼中存在泛型*/public static void main(String[] args) {    Map map = new HashMap();    map.put("hello","你好");    String hello = map.get("hello");    System.out.println(hello);}

          當(dāng)上述源代碼被編譯為class文件后,泛型被擦除且引入強(qiáng)制類型轉(zhuǎn)換

          public static void main(String[] args) {    HashMap map = new HashMap(); //類型擦除    map.put("hello", "你好");    String hello = (String)map.get("hello");//強(qiáng)制轉(zhuǎn)換    System.out.println(hello);}




          自動(dòng)裝箱與拆箱

          Java中的自動(dòng)裝箱與拆箱指的是基本數(shù)據(jù)類型與他們的包裝類型之間的相互轉(zhuǎn)換。

          我們知道Java是一門面向?qū)ο蟮恼Z(yǔ)言,在Java世界中有一句話是這么說的:“萬(wàn)物皆對(duì)象”。但是Java中的基本數(shù)據(jù)類型卻不是對(duì)象,他們不需要進(jìn)行new操作,也不能調(diào)用任何方法,這在使用的時(shí)候有諸多不便。因此Java為這些基本類型提供了包裝類,并且為了使用方便,提供了自動(dòng)裝箱與拆箱功能。自動(dòng)裝箱與拆箱在使用的過程中,其實(shí)是一個(gè)語(yǔ)法糖,內(nèi)部還是調(diào)用了相應(yīng)的函數(shù)進(jìn)行轉(zhuǎn)換。

          下面代碼演示了自動(dòng)裝箱和拆箱功能

          public static void main(String[] args) {    Integer a = 1;    int b = 2;    int c = a + b;    System.out.println(c);}

          經(jīng)過編譯后,代碼如下

          public static void main(String[] args) {    Integer a = Integer.valueOf(1); // 自動(dòng)裝箱    byte b = 2;    int c = a.intValue() + b;//自動(dòng)拆箱    System.out.println(c);}

          變長(zhǎng)參數(shù)

          所謂變長(zhǎng)參數(shù),就是方法可以接受長(zhǎng)度不定確定的參數(shù)。變長(zhǎng)參數(shù)特性是在JDK1.5中引入的,使用變長(zhǎng)參數(shù)有兩個(gè)條件,一是變長(zhǎng)的那一部分參數(shù)具有相同的類型,二是變長(zhǎng)參數(shù)必須位于方法參數(shù)列表的最后面。變長(zhǎng)參數(shù)同樣是Java中的語(yǔ)法糖,其內(nèi)部實(shí)現(xiàn)是Java數(shù)組。

          public class Varargs {    public static void print(String... args) {        for(String str : args){            System.out.println(str);        }    }
          public static void main(String[] args) { print("hello", "world"); }}

          編譯為class文件后如下,從中可以很明顯的看出變長(zhǎng)參數(shù)內(nèi)部是通過數(shù)組實(shí)現(xiàn)的

          public class Varargs {    public Varargs() {    }
          public static void print(String... args) { String[] var1 = args; int var2 = args.length; //增強(qiáng)for循環(huán)的數(shù)組實(shí)現(xiàn)方式 for(int var3 = 0; var3 < var2; ++var3) { String str = var1[var3]; System.out.println(str); }
          }
          public static void main(String[] args) { //變長(zhǎng)參數(shù)轉(zhuǎn)換為數(shù)組 print(new String[]{"hello", "world"}); }}

          增強(qiáng)for循環(huán)

          增強(qiáng)for循環(huán)與普通for循環(huán)相比,功能更強(qiáng)并且代碼更簡(jiǎn)潔。增強(qiáng)for循環(huán)的對(duì)象要么是一個(gè)數(shù)組,要么實(shí)現(xiàn)了Iterable接口。這個(gè)語(yǔ)法糖主要用來對(duì)數(shù)組或者集合進(jìn)行遍歷,其在循環(huán)過程中不能改變集合的大小。

          public static void main(String[] args) {    String[] params = new String[]{"hello","world"};    //增強(qiáng)for循環(huán)對(duì)象為數(shù)組    for(String str : params){        System.out.println(str);    }
          List lists = Arrays.asList("hello","world"); //增強(qiáng)for循環(huán)對(duì)象實(shí)現(xiàn)Iterable接口 for(String str : lists){ System.out.println(str); }}

          編譯后的class文件為

          public static void main(String[] args) {   String[] params = new String[]{"hello", "world"};   String[] lists = params;   int var3 = params.length;   //數(shù)組形式的增強(qiáng)for退化為普通for   for(int str = 0; str < var3; ++str) {       String str1 = lists[str];       System.out.println(str1);   }
          List var6 = Arrays.asList(new String[]{"hello", "world"}); Iterator var7 = var6.iterator(); //實(shí)現(xiàn)Iterable接口的增強(qiáng)for使用iterator接口進(jìn)行遍歷 while(var7.hasNext()) { String var8 = (String)var7.next(); System.out.println(var8); }
          }

          內(nèi)部類

          內(nèi)部類就是定義在一個(gè)類內(nèi)部的類 Java語(yǔ)言中之所以引入內(nèi)部類,是因?yàn)橛行r(shí)候一個(gè)類只在另一個(gè)類中有用,我們不想讓其在另外一個(gè)地方被使用。內(nèi)部類之所以是語(yǔ)法糖,是因?yàn)槠渲皇且粋€(gè)編譯時(shí)的概念,一旦編譯完成,編譯器就會(huì)為內(nèi)部類生成一個(gè)單獨(dú)的class文件,名為outer$innter.class。

          public class Outer {    class Inner{    }}

          使用javac編譯后,生成兩個(gè)class文件Outer.class和OuterInner.class,其中OuterInner.class,其中OuterInner.class的內(nèi)容如下:

          class Outer$Inner {    Outer$Inner(Outer var1) {        this.this$0 = var1;    }}

          內(nèi)部類分為四種:成員內(nèi)部類、局部?jī)?nèi)部類、匿名內(nèi)部類、靜態(tài)內(nèi)部類,每一種都有其用法,這里就不介紹了

          枚舉類型

          枚舉類型就是一些具有相同特性的類常量 java中類的定義使用class,枚舉類的定義使用enum。在Java的字節(jié)碼結(jié)構(gòu)中,其實(shí)并沒有枚舉類型,枚舉類型只是一個(gè)語(yǔ)法糖,在編譯完成后被編譯成一個(gè)普通的類。這個(gè)類繼承java.lang.Enum,并被final關(guān)鍵字修飾。

          public enum Fruit {    APPLE,ORINGE}

          使用jad對(duì)編譯后的class文件進(jìn)行反編譯后得到:

          //繼承java.lang.Enum并聲明為finalpublic final class Fruit extends Enum{
          public static Fruit[] values() { return (Fruit[])$VALUES.clone(); }
          public static Fruit valueOf(String s){ return (Fruit)Enum.valueOf(Fruit, s); }
          private Fruit(String s, int i){ super(s, i); } //枚舉類型常量 public static final Fruit APPLE; public static final Fruit ORANGE; private static final Fruit $VALUES[];//使用數(shù)組進(jìn)行維護(hù)
          static { APPLE = new Fruit("APPLE", 0); ORANGE = new Fruit("ORANGE", 1); $VALUES = (new Fruit[] { APPLE, ORANGE }); }}

          Java遠(yuǎn)不止這些語(yǔ)法糖,JDK7、JDK8添加的新特性都有很多高級(jí)的語(yǔ)法糖。



          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開更多互動(dòng)和交流。

          -?END -

          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天射天天干天天操 | 久久久无码精品成人A片小说 | 亚州老女人BB | 影音先锋成人电影 | 国产婷婷综合 |