[轉載]談談Java中的語法糖

原文談談Java中的語法糖

語法糖(Syntactic Sugar),也稱糖衣語法础倍,指在計算機語言中添加的某種語法烛占,這種語法對語言本身功能來說沒有什么影響,只是為了方便程序員的開發(fā)沟启,提高開發(fā)效率忆家。說白了,語法糖就是對現(xiàn)有語法的一個封裝德迹。

Java作為一種與平臺無關的高級語言芽卿,當然也含有語法糖,這些語法糖并不被虛擬機所支持胳搞,在編譯成字節(jié)碼階段就自動轉換成簡單常用語法卸例。一般來說Java中的語法糖主要有以下幾種:

  1. 泛型與類型擦除
  2. 自動裝箱與拆箱,變長參數(shù)肌毅、
  3. 增強for循環(huán)
  4. 內(nèi)部類與枚舉類

泛型與類型擦除

Java語言并不是一開始就支持泛型的筷转。在早期的JDK中,只能通過Object類是所有類型的父類和強制類型轉換來實現(xiàn)泛型的功能悬而。強制類型轉換的缺點就是把編譯期間的問題延遲到運行時呜舒,JVM并不能為我們提供編譯期間的檢查。

在JDK1.5中笨奠,Java語言引入了泛型機制袭蝗。但是這種泛型機制是通過類型擦除來實現(xiàn)的,即Java中的泛型只在程序源代碼中有效(源代碼階段提供類型檢查)艰躺,在編譯后的字節(jié)碼中自動用強制類型轉換進行替代呻袭。也就是說,Java語言中的泛型機制其實就是一顆語法糖腺兴,相較與C++左电、C#相比,其泛型實現(xiàn)實在是不那么優(yōu)雅页响。

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

當上述源代碼被編譯為class文件后篓足,泛型被擦除且引入強制類型轉換

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

自動裝箱與拆箱

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

我們知道Java是一門面向對象的語言闰蚕,在Java世界中有一句話是這么說的:“萬物皆對象”栈拖。但是Java中的基本數(shù)據(jù)類型卻不是對象,他們不需要進行new操作没陡,也不能調用任何方法涩哟,這在使用的時候有諸多不便索赏。因此Java為這些基本類型提供了包裝類,并且為了使用方便贴彼,提供了自動裝箱與拆箱功能潜腻。自動裝箱與拆箱在使用的過程中,其實是一個語法糖器仗,內(nèi)部還是調用了相應的函數(shù)進行轉換融涣。

下面代碼演示了自動裝箱和拆箱功能

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

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

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

變長參數(shù)

所謂變長參數(shù)精钮,就是方法可以接受長度不定確定的參數(shù)

變長參數(shù)特性是在JDK1.5中引入的威鹿,使用變長參數(shù)有兩個條件,一是變長的那一部分參數(shù)具有相同的類型轨香,二是變長參數(shù)必須位于方法參數(shù)列表的最后面忽你。變長參數(shù)同樣是Java中的語法糖,其內(nèi)部實現(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");
    }
}1234567891011

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

public class Varargs {
    public Varargs() {
    }

    public static void print(String... args) {
        String[] var1 = args;
        int var2 = args.length;
        //增強for循環(huán)的數(shù)組實現(xiàn)方式
        for(int var3 = 0; var3 < var2; ++var3) {
            String str = var1[var3];
            System.out.println(str);
        }

    }

    public static void main(String[] args) {
        //變長參數(shù)轉換為數(shù)組
        print(new String[]{"hello", "world"});
    }
}1234567891011121314151617181920

增強for循環(huán)

增強for循環(huán)與普通for循環(huán)相比,功能更強并且代碼更簡潔

增強for循環(huán)的對象要么是一個數(shù)組策橘,要么實現(xiàn)了Iterable接口炸渡。這個語法糖主要用來對數(shù)組或者集合進行遍歷,其在循環(huán)過程中不能改變集合的大小丽已。

public static void main(String[] args) {
    String[] params = new String[]{"hello","world"};
    //增強for循環(huán)對象為數(shù)組
    for(String str : params){
        System.out.println(str);
    }

    List<String> lists = Arrays.asList("hello","world");
    //增強for循環(huán)對象實現(xiàn)Iterable接口
    for(String str : lists){
        System.out.println(str);
    }
}12345678910111213

編譯后的class文件為

public static void main(String[] args) {
   String[] params = new String[]{"hello", "world"};
   String[] lists = params;
   int var3 = params.length;
   //數(shù)組形式的增強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();
   //實現(xiàn)Iterable接口的增強for使用iterator接口進行遍歷
   while(var7.hasNext()) {
       String var8 = (String)var7.next();
       System.out.println(var8);
   }

}12345678910111213141516171819

內(nèi)部類

內(nèi)部類就是定義在一個類內(nèi)部的類

Java語言中之所以引入內(nèi)部類蚌堵,是因為有些時候一個類只在另一個類中有用,我們不想讓其在另外一個地方被使用沛婴。內(nèi)部類之所以是語法糖吼畏,是因為其只是一個編譯時的概念,一旦編譯完成嘁灯,編譯器就會為內(nèi)部類生成一個單獨的class文件泻蚊,名為outer$innter.class。

public class Outer {
    class Inner{
    }
}1234

使用javac編譯后丑婿,生成兩個class文件Outer.class和Outer$性雄,其中Inner.class,其中Outer$Inner.class的內(nèi)容如下:

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

內(nèi)部類分為四種:成員內(nèi)部類羹奉、局部內(nèi)部類秒旋、匿名內(nèi)部類、靜態(tài)內(nèi)部類诀拭,每一種都有其用法迁筛,這里就不介紹了

枚舉類型

枚舉類型就是一些具有相同特性的類常量

java中類的定義使用class,枚舉類的定義使用enum耕挨。在Java的字節(jié)碼結構中细卧,其實并沒有枚舉類型尉桩,枚舉類型只是一個語法糖,在編譯完成后被編譯成一個普通的類贪庙。這個類繼承java.lang.Enum魄健,并被final關鍵字修飾。

public enum Fruit {
    APPLE,ORINGE
}123

使用jad對編譯后的class文件進行反編譯后得到:

//繼承java.lang.Enum并聲明為final
public 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ù)組進行維護

    static
    {
        APPLE = new Fruit("APPLE", 0);
        ORANGE = new Fruit("ORANGE", 1);
        $VALUES = (new Fruit[] {
            APPLE, ORANGE
        });
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末插勤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子革骨,更是在濱河造成了極大的恐慌农尖,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件良哲,死亡現(xiàn)場離奇詭異盛卡,居然都是意外死亡,警方通過查閱死者的電腦和手機筑凫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門滑沧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巍实,你說我怎么就攤上這事滓技。” “怎么了棚潦?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵令漂,是天一觀的道長。 經(jīng)常有香客問我丸边,道長叠必,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任妹窖,我火速辦了婚禮纬朝,結果婚禮上,老公的妹妹穿的比我還像新娘骄呼。我一直安慰自己共苛,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布谒麦。 她就那樣靜靜地躺著俄讹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绕德。 梳的紋絲不亂的頭發(fā)上患膛,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音耻蛇,去河邊找鬼踪蹬。 笑死胞此,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的跃捣。 我是一名探鬼主播漱牵,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疚漆!你這毒婦竟也來了酣胀?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤娶聘,失蹤者是張志新(化名)和其女友劉穎闻镶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丸升,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡铆农,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狡耻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墩剖。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夷狰,靈堂內(nèi)的尸體忽然破棺而出岭皂,到底是詐尸還是另有隱情,我是刑警寧澤沼头,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布蒲障,位于F島的核電站,受9級特大地震影響瘫证,放射性物質發(fā)生泄漏揉阎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一背捌、第九天 我趴在偏房一處隱蔽的房頂上張望毙籽。 院中可真熱鬧,春花似錦毡庆、人聲如沸坑赡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毅否。三九已至,卻和暖如春蝇刀,著一層夾襖步出監(jiān)牢的瞬間螟加,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捆探,地道東北人然爆。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像黍图,于是被迫代替她去往敵國和親曾雕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容

  • Scala與Java的關系 Scala與Java的關系是非常緊密的V弧剖张! 因為Scala是基于Java虛擬機,也就是...
    燈火gg閱讀 3,448評論 1 24
  • 《深入理解Java虛擬機》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分揩环。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,098評論 1 34
  • 第三章 4D系統(tǒng)---神奇坐標的誕生 小標題: (1)神奇坐標的誕生修械、4D領導力 (2)有關4D的驗證結論 蓋普洛...
    Jennie夏閱讀 329評論 0 0
  • #2017-1-4 每天一個關鍵詞#瑜伽動作 在納蘭瑜伽館的學習漸入佳境,11月報名學了一段時間检盼,12月去柬埔寨旅...
    勁汶閱讀 207評論 0 0
  • 這本書是一本教我們?nèi)绾握嬲鉀Q問題的書。 所謂問題是現(xiàn)實狀態(tài)與理想狀態(tài)的差距翘单。人們通常提出一個問題時吨枉,不會花費太多...
    liuyan_940f閱讀 229評論 0 0