java中為什么設計包裝類,Java 中為什么要設計包裝類

最近文章更新頻率慢了,因為最近在準備暑期實習,之前尋思著一邊復習一邊寫文章,兩全其美。后來發現一篇讀起來比較舒服的文章寫出來加上配圖得花上四五個小時甚至更多,但這個知識點我可能半個小時就能復習完了,春招在即,時間比較緊迫,所以最近文章可能改為一周一更或者一周兩更,希望各位理解。另外,有和我一樣在準備暑期實習的小伙伴可以聯系我互相交流

全文脈絡思維導圖如下:

e921e7d989ae7fb1fc7fd42b70f5bb84.png

1. 為什么需要包裝類

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

這樣,我們先自己實現一個簡單的包裝類,以包裝基本類型?int?為例://?包裝類?MyInt

public?class?MyInt?{

private?int?number;?//?基本數據類型

public?Int?(int?number){?//?構造函數,傳入基本數據類型

this.number?=?number;

}

public?int?intValue(){?//?取得包裝類中的數據

return?this.number;

}

}

測試一下這個包裝類:public?static?void?main(String[]?args)?{

MyInt?temp?=?new?Int(100);?//?100?是基本數據類型,?將基本數據類型包裝后成為對象

int?result?=?temp.intValue();?//?從對象中取得基本數據類型

System.out.println(result);

}

當然,我們自己實現的這個包裝類非常簡單,Java 給我們提供了更完善的內置包裝類:基本類型對應的包裝類(位于 java.lang 包中)byteByte

shortShort

intInteger

longLong

floatFloat

doubleDouble

charCharacter

booleanBoolean

前 6 個類派生于公共的超類?Number,而?Character?和?Boolean?是?Object?的直接子類。

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

dddd9b73fe8996f9a8ff45d6fb9aeef2.png

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

2. 裝箱與拆箱

OK,現在我們已經知道了,存在基本數據類型與其對應的包裝類,那么,他們之間互相的轉換操作就稱為裝箱與拆箱:裝箱:將基本數據類型轉換成包裝類(每個包裝類的構造方法都可以接收各自數據類型的變量)

拆箱:從包裝類之中取出被包裝的基本類型數據(使用包裝類的 xxxValue 方法)

下面以?Integer?為例,我們來看看 Java 內置的包裝類是如何進行拆裝箱的:Integer?obj?=?new?Integer(10);??//?自動裝箱

int?temp?=?obj.intValue();??//?自動拆箱

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

3bb4218fec607084134463ea44ea8218.png

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

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

還是以?Integer?為例我們來看看自動拆裝箱的過程:Integer?obj?=?10;??//?自動裝箱.?基本數據類型?int?->?包裝類?Integer

int?temp?=?obj;??//?自動拆箱.?Integer?->?int

obj?++;?//?直接利用包裝類的對象進行數學計算

System.out.println(temp?*?obj);

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

804b644453cca996733df1ef50106151.png

我們來看看這段代碼反編譯后的文件,底層到底是什么原理:Integer?obj?=?Integer.valueOf(10);

int?temp?=?obj.intValue();

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

3. 不簡單的 Integer.valueOf

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

7aae1022fb9d461c0aebdfdf3ba35dcb.png

IntegerCache?又是啥,點進去看看:

4283ab11e787700c4db5d6ed8360e106.png

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

回到?valueOf?的源碼:它首先會判斷 int 類型的實參 i 是否在可緩存區間內,如果在,就直接從緩存?IntegerCache?中獲取對應的?Integer?對象;如果不在緩存區間內,則會 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?的緩存區間內,所以這個?Integer?對象會被存入緩存。而在創建 a2 的時候,由于其值和 a1 相等,所以直接從緩存中取出值為 127 的?Integer?對象給 a2 使用,也就是說,a1 和 a2 這兩個?Integer?的對象引用都指向同一個地址。

8d0e30c9ee4b74bfb9a6f2417e490128.png

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

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

1f5b97f3dca2197fbdd725629c54a7c9.png

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

4. Object 類可以接收所有數據類型

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

不信你可以試試,直接用?Object?類接收一個基本數據類型?int,完全是可以的。Object?obj?=?10;

int?temp?=?(Integer)?obj;

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

48a500b49b3b2343c770e5a9b47581ad.png

5. 包裝類在集合中的廣泛使用

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

往這個列表中添加?int?型數據:list.add(3);

上面這個調用在底層將會發生自動裝箱操作:list.add?(Integer.valueOf(3));

基本數據類型?int?會被轉換成?Integer?對象存入集合中。

我們再來從這個集合中根據某個下標 i 獲取對應的?Integer?對象,并用基本數據類型?int?接收:int?n?=?list.get(i);

上面這個調用在底層將會發生自動拆箱操作:int?n?=?list.get(i).intValue();

6. 數據類型轉換

另外,除了在集合中的廣泛應用,包裝類還包含一個重要功能,那就是提供將String型數據變為基本數據類型的方法,使用幾個代表的類做說明:

Integer:

30498cf0a2e4f4c7e86d53bf74c62995.png

Double:

de2b6d72a0a83b428907d8f5f633f69c.png

Boolean:

c008c3bd0179f3d188b78b7ae3773ab0.png

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

int?temp?=?Integer.parseInt(str);//?String?->?int

System.out.println(temp?*?2);?//?20

需要特別注意的是:Character?類里面并不存在字符串變為字符的方法,因為?String?類中已經有一個?charAt()的方法可以根據索引取出字符內容。

b7fdcdae9f89f1b263b9e1ed9534ae01.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457149.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457149.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457149.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bfc

BFC 已經是一個耳聽熟聞的詞語了&#xff0c;網上有許多關于 BFC 的文章&#xff0c;介紹了如何觸發 BFC 以及 BFC 的一些用處&#xff08;如清浮動&#xff0c;防止 margin 重疊等&#xff09;。雖然我知道如何利用 BFC 解決這些問題&#xff0c;但當別人問我 BFC 是什么&…

Python語法異常 Exception

常見異常&#xff1a;Exception 所有異常的基類AttributeError 特性應用或賦值失敗時引發IOError 試圖打開不存在的文件時引發IndexError 在使用序列中不存在的索引時引發KeyError …

Python的Django框架中forms表單類的使用方法詳解

Form Form的驗證思路 前端&#xff1a;form表單 后臺&#xff1a;創建form類&#xff0c;當請求到來時&#xff0c;先匹配&#xff0c;匹配出正確和錯誤信息。 Django的Form驗證實例&#xff1a; 創建project&#xff0c;進行基礎配置文件配置 settings.py settings.py之…

java讀取gpx文件,從Leaflet導出GPX文件

我想要做的是讓用戶通過選擇Leaflet中的一些GeoJson功能來創建GPX文件 . 我這樣做的方法是創建一個新的GeoJson圖層來存儲所選的特征&#xff0c;然后用一個名為togpx(https://github.com/tyrasd/togpx)的插件將其轉換為gpx . 現在我有一個gpx文件&#xff0c;但我沒有t know h…

Mono Compatibility

The easiest way to describe what Mono currently supports is:Everything in .NET 4.5 except WPF, WWF, and with limited WCF and limited ASP.NET 4.5 async stack. System.Web and WCF are candidates for ‘almost immediate’ porting from the .NET reference source …

Python的Django框架中forms表單類的使用方法詳解2

用戶表單是Web端的一項基本功能,大而全的Django框架中自然帶有現成的基礎form對象,本文就Python的Django框架中forms表單類的使用方法詳解。 Form表單的功能 自動生成HTML表單元素檢查表單數據的合法性如果驗證錯誤&#xff0c;重新顯示表單&#xff08;數據不會重置&#xf…

生動形象的理解API是如何工作的!

API(Application Programming Interface,應用程序編程接口) 簡單來說&#xff0c;就是其他人開發出來一塊程序&#xff0c;你想用&#xff0c;他會告訴你調用哪個函數&#xff0c;給這個函數傳什么參數&#xff0c;然后又會返回給你一個什么樣的結果&#xff0c;你不需要知道他…

ann matlab,人工神經網絡ann及其matlab仿真.ppt

人工神經網絡ann及其matlab仿真人工神經網絡 的研究方法及應用劉 長 安2004. 12. 31 引 言 利用機器模仿人類的智能是長期以來人們認識自然、改造自然和認識自身的理想。 研究ANN目的&#xff1a; (1)探索和模擬人的感覺、思維和行為的規律&#xff0c;設計具有人類智能的計算機…

字符串與樹的結合

https://leetcode.com/problems/scramble-string/?tabDescription 雖然題目不常見&#xff0c;但是里面關于字符串調轉和遞歸的思路&#xff0c;還是很有代表性的。 https://discuss.leetcode.com/topic/14337/share-my-4ms-c-recursive-solution/2 這個解法也把里面關于遞歸的…

ubuntu 安裝過程所需軟件

ubuntu 開發過程好用的軟件 Remarkable 一個用于書寫文檔的好工具&#xff0c;包括方便書寫數學公式。安裝過程 點擊上面“remarkable”下載.deb文件&#xff0c;然后雙擊會跳轉到ubuntun的軟件安裝中心&#xff0c;點擊install進行安裝。 sublime text3 配置 自定義快捷鍵Pref…

Day05-循環和列表字符串、元組和字典

一、字符串 字符串就是由若干個不同的unicode字符組成的不可變序列 1 .字符串創建 #單引號字符串 str1 天要下雨&#xff0c;娘要嫁人&#xff0c;由他去吧 str2 str() #空串 str3 str([10,20,30]) ? #雙引號字符串 str2 "天要下雨&#xff0c;娘要嫁人&#xff…

@查看MySQL版本的方法

1.在終端下:mysql -V. [rootlocalhost bin]# mysql -V; mysql Ver 14.14 Distrib 5.6.21, for Linux (x86_64) using EditLine wrapper [rootlocalhost bin]# mysql -v; ERROR 1045 (28000): Access denied for user rootlocalhost (using password: NO) 注意&#xff0c;這…

echarts 柱狀圖 ,顏色和顯示設置

最近在使用echart開發圖標&#xff0c;api里面雖然有些設置&#xff0c;但是如果想讓柱狀圖每個柱的顏色都不相同&#xff0c;簡單的通過color設置是沒有作用的&#xff0c;這里&#xff0c;就要用到其他的方式了 下面只是列舉下我認為比較常用的&#xff0c;其他的比較簡單&am…

Pycharm 專業版 導入系統pip安裝的包

Pycharm 專業版 導入系統pip安裝的包 在setting 中找到project interpeter ,點擊設置圖標&#xff0c;點擊Add&#xff0c;得到如圖所示選擇 System Interpreter即可,這樣 用pip安裝的包都加再進來了

nodejs express

2019獨角獸企業重金招聘Python工程師標準>>> 創建express服務器 //app.js文件 var express require(express); var app express(); //指定更目錄顯示的內容 app.get(/, function(req, res){ res.send(Hello World); }); //指定監聽端口 var server app.listen(…

JS常見知識點

1、寫一個按照下面方式調用都能正常工作的 sum 方法 console.log(sum(2,3)); // Outputs 5 console.log(sum(2)(3)); // Outputs 5 解決方案 function sum() {var fir arguments[0];if (arguments.length 2) {return arguments[0] arguments[1]} else {return function (sec…

格雷碼 matlab,基于格雷碼的結構光重建代碼(MATLAB版本)

【實例簡介】該代碼為brown university相關技術人員編寫&#xff0c;旨在用于學習研究3D結構光的原理、算法實現和應用。由于原有的網站( http://mesh.brown.edu/byo3d/index.html )近期無法訪問&#xff0c;為了便于3D愛好者可以方便學習相關內容&#xff0c;特將該網站部分代…

Day06-函數

函數 一、集合&#xff08;set) 特點:不允許有重復元素&#xff0c;如果添加重復元素&#xff0c;則會自動過濾&#xff0c;可以進行交集、并集的運算。 本質&#xff1a;無序且無重復元素的數據結構 1 創建集合 s1 set() #空集合 不能是{}&#xff0c;這是字典 s2 {1…

在TextView中實時顯示數據

//下面實時更新顯示在textView中的數據handler new Handler();runnable new Runnable(){Overridepublic void run(){// TODO Auto-generated method pushupTextView.setText(Integer.toString(Number.pushup_number)); handler.postDelayed(this, 1000); }}; handle…

DuangDuangDuang!碼云項目的 Readme.md 特殊技能

為什么80%的碼農都做不了架構師&#xff1f;>>> 我們在 碼云 上創建新項目的時候&#xff0c;常常會看到默認使用 README 文件初始化該項目&#xff08;如圖1 所示&#xff09;&#xff0c;然后在新建項目的根目錄下就會生成一個 README.md 文件&#xff08;如圖2 …