99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Java 語(yǔ)法糖

2018-09-28 19:22 更新

Java 語(yǔ)法糖

語(yǔ)法糖(Syntactic Sugar),也稱糖衣語(yǔ)法,是由英國(guó)計(jì)算機(jī)學(xué)家 Peter.J.Landin 發(fā)明的一個(gè)術(shù)語(yǔ),指在計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,這種語(yǔ)法對(duì)語(yǔ)言的功能并沒(méi)有影響,但是更方便程序員使用。Java 中最常用的語(yǔ)法糖主要有泛型、變長(zhǎng)參數(shù)、條件編譯、自動(dòng)拆裝箱、內(nèi)部類等。虛擬機(jī)并不支持這些語(yǔ)法,它們?cè)诰幾g階段就被還原回了簡(jiǎn)單的基礎(chǔ)語(yǔ)法結(jié)構(gòu),這個(gè)過(guò)程成為解語(yǔ)法糖。

泛型是 JDK1.5 之后引入的一項(xiàng)新特性,Java 語(yǔ)言在還沒(méi)有出現(xiàn)泛型時(shí),只能通過(guò) Object 是所有類型的父類和類型強(qiáng)制轉(zhuǎn)換這兩個(gè)特點(diǎn)的配合來(lái)實(shí)現(xiàn)泛型的功能,這樣實(shí)現(xiàn)的泛型功能要在程序運(yùn)行期才能知道 Object 真正的對(duì)象類型,在 javac 編譯期,編譯器無(wú)法檢查這個(gè) Object 的強(qiáng)制轉(zhuǎn)型是否成功,這便將一些風(fēng)險(xiǎn)轉(zhuǎn)接到了程序運(yùn)行期中。

Java 語(yǔ)言在 JDK1.5 之后引入的泛型實(shí)際上只在程序源碼中存在,在編譯后的字節(jié)碼文件中,就已經(jīng)被替換為了原來(lái)的原生類型,并且在相應(yīng)的地方插入了強(qiáng)制轉(zhuǎn)型代碼,因此對(duì)于運(yùn)行期的Java語(yǔ)言來(lái)說(shuō),ArrayList和 ArrayList就是同一個(gè)類。所以泛型技術(shù)實(shí)際上是 Java 語(yǔ)言的一顆語(yǔ)法糖,Java 語(yǔ)言中的泛型實(shí)現(xiàn)方法稱為類型擦除,基于這種方法實(shí)現(xiàn)的泛型被稱為偽泛型。

下面是一段簡(jiǎn)單的 Java 泛型代碼:

Map<Integer,String> map = new HashMap<Integer,String>();  
map.put(1,"No.1");  
map.put(2,"No.2");  
System.out.println(map.get(1));  
System.out.println(map.get(2));  

將這段 Java 代碼編譯成 Class 文件,然后再用字節(jié)碼反編譯工具進(jìn)行反編譯后,將會(huì)發(fā)現(xiàn)泛型都變回了原生類型,如下面的代碼所示:

Map map = new HashMap();  
map.put(1,"No.1");  
map.put(2,"No.2");  
System.out.println((String)map.get(1));  
System.out.println((String)map.get(2));  

為了更詳細(xì)地說(shuō)明類型擦除,再看如下代碼:

import java.util.List;  
public class FanxingTest{  
    public void method(List<String> list){  
        System.out.println("List String");  
    }  
    public void method(List<Integer> list){  
        System.out.println("List Int");  
    }  
}  

當(dāng)用 javac 編譯器編譯這段代碼時(shí),報(bào)出了如下錯(cuò)誤:

FanxingTest.java:3: 名稱沖突:method(java.util.List<java.lang.String>) 和 method

(java.util.List<java.lang.Integer>) 具有相同疑符

        public void method(List<String> list){

                    ^

FanxingTest.java:6: 名稱沖突:method(java.util.List<java.lang.Integer>) 和 metho

d(java.util.List<java.lang.String>) 具有相同疑符

        public void method(List<Integer> list){

                    ^

2 錯(cuò)誤

是因?yàn)榉盒?List 和 List 編譯后都被擦除了,變成了一樣的原生類型 List,擦除動(dòng)作導(dǎo)致這兩個(gè)方法的特征簽名變得一模一樣,在 Class 類文件結(jié)構(gòu)一文中講過(guò),Class 文件中不能存在特征簽名相同的方法。

把以上代碼修改如下:

import java.util.List;  
public class FanxingTest{  
    public int method(List<String> list){  
        System.out.println("List String");  
        return 1;  
    }  
    public boolean method(List<Integer> list){  
        System.out.println("List Int");  
        return true;  
    }  
}  

發(fā)現(xiàn)這時(shí)編譯可以通過(guò)了(注意:Java 語(yǔ)言中 true 和 1 沒(méi)有關(guān)聯(lián),二者屬于不同的類型,不能相互轉(zhuǎn)換,不存在 C 語(yǔ)言中整數(shù)值非零即真的情況)。兩個(gè)不同類型的返回值的加入,使得方法的重載成功了。這是為什么呢?

我們知道,Java 代碼中的方法特征簽名只包括了方法名稱、參數(shù)順序和參數(shù)類型,并不包括方法的返回值,因此方法的返回值并不參與重載方法的選擇,這樣看來(lái)為重載方法加入返回值貌似是多余的。對(duì)于重載方法的選擇來(lái)說(shuō),這確實(shí)是多余的,但我們現(xiàn)在要解決的問(wèn)題是讓上述代碼能通過(guò)編譯,讓兩個(gè)重載方法能夠合理地共存于同一個(gè) Class 文件之中,這就要看字節(jié)碼的方法特征簽名,它不僅包括了 Java 代碼中方法特征簽名中所包含的那些信息,還包括方法返回值及受查異常表。為兩個(gè)重載方法加入不同的返回值后,因?yàn)橛辛瞬煌淖止?jié)碼特征簽名,它們便可以共存于一個(gè) Class 文件之中。

自動(dòng)拆裝箱、變長(zhǎng)參數(shù)等語(yǔ)法糖也都是在編譯階段就把它們?cè)撜Z(yǔ)法糖結(jié)構(gòu)還原為了原生的語(yǔ)法結(jié)構(gòu),因此在 Class 文件中也只存在其對(duì)應(yīng)的原生類型,這里不再一一說(shuō)明。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)