最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析Java中為什么要設計包裝類

 更新時間:2021年06月21日 14:17:08   作者:飛天小牛肉  
我們知道Java是一個面相對象的編程語言,基本類型并不具有對象的性質,為了讓基本類型也具有對象的特征,就出現(xiàn)了包裝類型,它相當于將基本類型“包裝起來”,使得它具有了對象的性質,并且為其添加了屬性和方法,豐富了基本類型的操作

一、為什么需要包裝類

在 Java 中,萬物皆對象,所有的操作都要求用對象的形式進行描述。但是 Java 中除了對象(引用類型)還有八大基本類型,它們不是對象。那么,為了把基本類型轉換成對象,最簡單的做法就是將基本類型作為一個類的屬性保存起來,也就是把基本數(shù)據(jù)類型包裝一下,這也就是包裝類的由來。

這樣,我們先自己實現(xiàn)一個簡單的包裝類,以包裝基本類型 int 為例:

// 包裝類 MyInt
public class MyInt {
    private int number; // 基本數(shù)據(jù)類型
    
    public Int (int number){ // 構造函數(shù),傳入基本數(shù)據(jù)類型
        this.number = number;
    }
    
    public int intValue(){ // 取得包裝類中的數(shù)據(jù)
        return this.number;
    }
}

測試一下這個包裝類:

public static void main(String[] args) {
    MyInt temp = new Int(100); // 100 是基本數(shù)據(jù)類型, 將基本數(shù)據(jù)類型包裝后成為對象
    int result = temp.intValue(); // 從對象中取得基本數(shù)據(jù)類型
    System.out.println(result);
}

當然,我們自己實現(xiàn)的這個包裝類非常簡單,Java 給我們提供了更完善的內置包裝類:

基本類型 對應的包裝類(位于 java.lang 包中)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

前 6 個類派生于公共的超類 Number,而 CharacterBooleanObject 的直接子類。

來看看包裝類的聲明,以 Integer 為例:

final 修飾,也就是說 Java 內置的包裝類是無法被繼承的。

二、裝箱與拆箱

OK,現(xiàn)在我們已經知道了,存在基本數(shù)據(jù)類型與其對應的包裝類,那么,他們之間互相的轉換操作就稱為裝箱與拆箱:

  • 裝箱:將基本數(shù)據(jù)類型轉換成包裝類(每個包裝類的構造方法都可以接收各自數(shù)據(jù)類型的變量)
  • 拆箱:從包裝類之中取出被包裝的基本類型數(shù)據(jù)(使用包裝類的 xxxValue 方法)

下面以 Integer 為例,我們來看看 Java 內置的包裝類是如何進行拆裝箱的:

Integer obj = new Integer(10);  // 自動裝箱
int temp = obj.intValue();  	// 自動拆箱

可以看出,和上面我們自己寫的包裝類使用方式基本一樣,事實上,Integer 中的這兩個方法其底層實現(xiàn)和我們上述寫的代碼也是差不多的。

不知道各位發(fā)現(xiàn)沒,value 被聲明為 final 了,也就是說一旦構造了包裝器,就不允許更改包裝在其中的值。

另外,需要注意的是,這種形式的代碼是 JDK 1.5 以前的?。?!JDK 1.5 之后,Java 設計者為了方便開發(fā)提供了自動裝箱與自動拆箱的機制,并且可以直接利用包裝類的對象進行數(shù)學計算。

還是以 Integer 為例我們來看看自動拆裝箱的過程:

Integer obj = 10;  	// 自動裝箱. 基本數(shù)據(jù)類型 int -> 包裝類 Integer
int temp = obj;  	// 自動拆箱. Integer -> int
obj ++; // 直接利用包裝類的對象進行數(shù)學計算
System.out.println(temp * obj); 

看見沒有,基本數(shù)據(jù)類型到包裝類的轉換,不需要像上面一樣使用構造函數(shù),直接 = 就完事兒;同樣的,包裝類到基本數(shù)據(jù)類型的轉換,也不需要我們手動調用包裝類的 xxxValue 方法了,直接 = 就能完成拆箱。這也是將它們稱之為自動的原因。

我們來看看這段代碼反編譯后的文件,底層到底是什么原理:

Integer obj = Integer.valueOf(10);
int temp = obj.intValue();

可以看見,自動裝箱的底層原理是調用了包裝類的 valueOf 方法,而自動拆箱的底層調用了包裝類的 intValue() 方法。

三、不簡單的 Integer.valueOf

我們上面已經看過了用于自動拆箱的 intValue 方法的源碼,非常簡單。接下來咱來看看用于自動裝箱的 valueOf,其他包裝類倒沒什么好說的,不過 Integer 中的這個方法還是有點東西的:

IntegerCache 又是啥,點進去看看:

IntegerCacheInteger 類中的靜態(tài)內部類,綜合這兩段代碼,我們大概也能知道,IntegerCache 其實就是個緩存,其中定義了一個緩沖區(qū) cache,用于存儲 Integer 類型的數(shù)據(jù),緩存區(qū)間是 [-128, 127]。

回到 valueOf 的源碼:它首先會判斷 int 類型的實參 i 是否在可緩存區(qū)間內,如果在,就直接從緩存 IntegerCache 中獲取對應的 Integer 對象;如果不在緩存區(qū)間內,則會 new 一個新的 Integer 對象。

結合這個特性,我們來看一個題目,兩種類似的代碼邏輯,但是卻得到完全相反的結果。:

public static void main(String args[]) {
    Integer a1 = 127;
    Integer a2 = 127;
    System.out.println(a1 == a2); // true

    Integer b1 = 128;
    Integer b2 = 128;
    System.out.println(b1 == b2); // false
}

我們知道,== 擁有兩種應用場景:

  • 對于引用類型來說,判斷的是內存地址是否相等
  • 對于基本類型來說,判斷的是值是否相等

從 a1 開始看,由于其值在 InterCache 的緩存區(qū)間內,所以這個 Integer 對象會被存入緩存。而在創(chuàng)建 a2 的時候,由于其值和 a1 相等,所以直接從緩存中取出值為 127 的 Integer 對象給 a2 使用,也就是說,a1 和 a2 這兩個 Integer 的對象引用都指向同一個地址。

對于 b1 和 b2 來說,由于 128 不在 IntegerCache 的緩存區(qū)間內,那就只能自己老老實實開辟空間了,所以 b1 和 b2 指向不同的內存地址。

很顯然,由于 InterCache 緩存機制的存在,可能會讓我們在編程的時候出現(xiàn)困惑,因此最好使用 .equals 方法來比較 Integer 值是否相等。Integer 重寫了 .equals 方法:

當然,其他包裝類雖然沒有緩存機制,但是也都重載了 .equals 方法,用于根據(jù)值來判斷是否相等。因此,得出結論,使用 equals 方法來比較兩個包裝類對象的值。

四、Object 類可以接收所有數(shù)據(jù)類型

綜上,有了自動拆裝箱機制,基本數(shù)據(jù)類型可以自動的被轉為包裝類,而 Object 是所有類的父類,也就是說,Object 可以接收所有的數(shù)據(jù)類型了(引用類型、基本類型)!?。?/p>

不信你可以試試,直接用 Object 類接收一個基本數(shù)據(jù)類型 int,完全是可以的。

Object obj = 10;
int temp = (Integer) obj;

解釋一下上面這段代碼發(fā)生了什么,下面這張圖很重要,大家仔細看:

五、包裝類在集合中的廣泛使用

其實包裝類最常見的使用就是在集合中,因為集合不允許存儲基本類型的數(shù)據(jù),只能存儲引用類型的數(shù)據(jù)。那如果我們想要存儲 1、2、3 這樣的基本類型數(shù)據(jù)怎么辦?舉個例子,我們可以如下聲明一個 Integer 對象的數(shù)組列表:

ArrayList<Integer> list = new ArrayList<>();

往這個列表中添加 int 型數(shù)據(jù):

list.add(3); 

上面這個調用在底層將會發(fā)生自動裝箱操作:

list.add (Integer.valueOf(3));

基本數(shù)據(jù)類型 int 會被轉換成 Integer 對象存入集合中。

我們再來從這個集合中根據(jù)某個下標 i 獲取對應的 Integer 對象,并用基本數(shù)據(jù)類型 int 接收:

int n = list.get(i);

上面這個調用在底層將會發(fā)生自動拆箱操作:

int n = list.get(i).intValue();

六、數(shù)據(jù)類型轉換

另外,除了在集合中的廣泛應用,包裝類還包含一個重要功能,那就是提供將String型數(shù)據(jù)變?yōu)榛緮?shù)據(jù)類型的方法,使用幾個代表的類做說明:

Integer

Double

Boolean

這些方法均被 static 標識,也就是說它們被各自對應的所有對象共同維護,直接通過類名訪問該方法。舉個例子:

String str = "10";
int temp = Integer.parseInt(str);// String -> int
System.out.println(temp * 2); // 20

需要特別注意的是:Character 類里面并不存在字符串變?yōu)樽址姆椒ǎ驗?String 類中已經有一個 charAt()的方法可以根據(jù)索引取出字符內容。

以上就是淺析Java中為什么要設計包裝類的詳細內容,更多關于Java 設計包裝類的資料請關注腳本之家其它相關文章!

相關文章

  • 解決@CachePut設置的key值無法與@CacheValue的值匹配問題

    解決@CachePut設置的key值無法與@CacheValue的值匹配問題

    這篇文章主要介紹了解決@CachePut設置的key的值無法與@CacheValue的值匹配問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 聊聊Spring?Boot如何配置多個Kafka數(shù)據(jù)源

    聊聊Spring?Boot如何配置多個Kafka數(shù)據(jù)源

    這篇文章主要介紹了Spring?Boot配置多個Kafka數(shù)據(jù)源的相關知識,包括生產者、消費者配置,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-10-10
  • SpringBoot日程管理Quartz與定時任務Task實現(xiàn)詳解

    SpringBoot日程管理Quartz與定時任務Task實現(xiàn)詳解

    定時任務是企業(yè)級開發(fā)中必不可少的組成部分,諸如長周期業(yè)務數(shù)據(jù)的計算,例如年度報表,諸如系統(tǒng)臟數(shù)據(jù)的處理,再比如系統(tǒng)性能監(jiān)控報告,還有搶購類活動的商品上架,這些都離不開定時任務。本節(jié)將介紹兩種不同的定時任務技術
    2022-09-09
  • Maven+SSM框架實現(xiàn)簡單的增刪改查

    Maven+SSM框架實現(xiàn)簡單的增刪改查

    這篇文章主要介紹了Maven+SSM框架實現(xiàn)簡單的增刪改查,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Spring實戰(zhàn)之協(xié)調作用域不同步的Bean操作示例

    Spring實戰(zhàn)之協(xié)調作用域不同步的Bean操作示例

    這篇文章主要介紹了Spring實戰(zhàn)之協(xié)調作用域不同步的Bean操作,結合實例形式分析了Spring協(xié)調作用域不同步的Bean相關配置及使用技巧,需要的朋友可以參考下
    2019-11-11
  • SpringBoot實現(xiàn)數(shù)據(jù)預熱的方式小結

    SpringBoot實現(xiàn)數(shù)據(jù)預熱的方式小結

    這里用到的數(shù)據(jù)預熱,就是在項目啟動時將一些數(shù)據(jù)量較大的數(shù)據(jù)加載到緩存中(筆者這里用的Redis),那么在項目啟動有哪些方式可以實現(xiàn)數(shù)據(jù)預熱呢,本文就來給大家講講幾種實現(xiàn)數(shù)據(jù)預熱的方式,需要的朋友可以參考下
    2023-09-09
  • Java JDK 動態(tài)代理的使用方法示例

    Java JDK 動態(tài)代理的使用方法示例

    Java 動態(tài)代理機制以巧妙的方式近乎完美地實踐了代理模式的設計理念。下面這篇文章主要給大家分享了關于Java JDK 動態(tài)代理的使用方法示例,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-07-07
  • 詳解JAVA 弱引用

    詳解JAVA 弱引用

    這篇文章主要介紹了 JAVA 弱引用的相關資料,幫助大家更好的理解和學習java引用對象,感興趣的朋友可以了解下
    2020-08-08
  • Java Jedis NOAUTH Authentication required問題解決方法

    Java Jedis NOAUTH Authentication required問題解決方法

    這篇文章主要介紹了Java Jedis NOAUTH Authentication required問題解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • Spring+SpringMVC+MyBatis深入學習及搭建(二)之MyBatis原始Dao開發(fā)和mapper代理開發(fā)

    Spring+SpringMVC+MyBatis深入學習及搭建(二)之MyBatis原始Dao開發(fā)和mapper代理開發(fā)

    這篇文章主要介紹了Spring+SpringMVC+MyBatis深入學習及搭建(二)之MyBatis原始Dao開發(fā)和mapper代理開發(fā),需要的朋友可以參考下
    2017-05-05

最新評論

婺源县| 合作市| 青川县| 西丰县| 澄迈县| 温泉县| 固原市| 台南县| 永修县| 逊克县| 虞城县| 浦江县| 葵青区| 安国市| 酉阳| 阿坝| 英德市| 济宁市| 饶平县| 尚志市| 新巴尔虎右旗| 长垣县| 蓬溪县| 大洼县| 万宁市| 霍州市| 金阳县| 孟连| 伊川县| 聊城市| 定边县| 精河县| 繁峙县| 昆明市| 东丽区| 鹿邑县| 嘉禾县| 五大连池市| 思南县| 灌阳县| 永和县|