Java_語法基礎_優先選擇基本類型

包裝類型是一個類,它提供了諸如構造方法、類型轉換、比較等非常實用的功能,而且在Java5之後又實現了與基本類型之間的自動轉換,這使包裝類型如虎添翼,更是應用廣泛了,在開發中包裝類型已經隨處可見,但無論是從安全性、性能方面來說,還是從穩定性方面來說,基本類型都是首選方案。我們來看一段代碼:

package deep;

public class Client {

    public static void main(String[] args) {
        Client client = new Client();
        int i = 140;
        // 分別傳遞int類型和Integer類型
        client.f(i);
        client.f(Integer.valueOf(i));
    }

    private void f(long i) {
        System.out.println("基本類型的方法被調用");
    }

    private void f(Long i) {
        System.out.println("包裝類型的方法被調用");
    }
}

運行結果:
基本類型的方法被調用
基本類型的方法被調用

client.f(i)的輸出是正常的,那第二個輸出就讓人困惑了,爲什麼會調用f(long a)方法呢?這是因爲自動裝箱有一個重要的原則:基本類型可以先加寬,再轉變成寬類型的包裝類型,但不能直接轉變成款類型的包裝類型。這句話比較拗口,簡單地說就是,int可以加寬轉變成long,然後再轉變成Long對象,但不能直接轉變成包裝類型,注意這裏指的都是自動轉換,你是通過構造函數生成。爲了解釋這個原則,我們再來看一個例子:

package deep;

public class Client {

    public static void main(String[] args) {
        int i = 140;
        f(i);
    }

    private static void f(Long i) {
    }

}

這段程序編譯時通不過的,因爲i是一個int類型,不能自動轉變成Long
型。但是修改成以下代碼就可以編譯通過了:

package deep;

public class Client {

    public static void main(String[] args) {
        int i = 140;
        long l = (long) i;
        f(l);
    }

    private static void f(Long i) {
    }

}

這就是int先加寬轉變爲long型,然後自動轉換成Long型。規則說明白了,我們繼續來看f(Integer.valueOf(i))是如何調用的,Integer.valueOf(i)返回的是一個Integer對象,這沒錯,但是Integer和int是可以互相轉換的。沒有f(Integer i)方法?沒關係,編譯器會嘗試轉換成int類型的實參調用,OK,這次成功了,與f(i)相同了,於是乎被加寬轉變成long型——結果也很明顯了,整個f(Integer.valueOf(i))的執行過程是這樣的:

  • i通過valueOf方法包裝成一個Integer對象。
  • 由於沒有f(Integer i)方法,編譯器“聰明”地把Integer對象轉換成int
  • int自動拓寬爲long,編譯結束

使用包裝類型確實有方便的地方,但是也會引起一些不必要的困惑,比如我們這個例子,如果f()的兩個重載方法使用的是基本類型,而且實參也是基本類型,就不會產生以上問題,而且程序的可讀性更強。自動裝箱(拆箱)雖然很方便,但引起的問題也非常嚴重——我們甚至都不知道執行的是哪個方法。

發佈了133 篇原創文章 · 獲贊 11 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章