成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入淺出了解“裝箱與拆箱”

FullStackDeveloper / 1929人閱讀

摘要:本章部分內(nèi)容從源碼中解讀一些自動裝箱與拆箱的原理,以及會出現(xiàn)的一些陷阱已經(jīng)性能等。例題分析我們通過幾個經(jīng)典的問題,來看看大家到底理解了裝箱與拆箱的知識點沒。


每章一點正能量:每當你想要放棄的時候,就想想是為了什么才一路堅持到現(xiàn)在。
前言

最近在回顧復習Java基礎(chǔ)中的一些知識點,發(fā)現(xiàn)了一些以前見過但是沒有留意卻特別有意思的知識特性,比如這次想分享的Java中一個常見的特性:自動裝箱與拆箱。這個知識點和特性其實在我們開發(fā)過程中經(jīng)常會遇到。同時我們也會去使用一些基本數(shù)據(jù)類型或者是封裝數(shù)據(jù)類型,但是對于他們之間的一些轉(zhuǎn)換等特性可能不是特別清楚。也可能出現(xiàn)在我們的面試中。本章部分內(nèi)容從源碼中解讀一些自動裝箱與拆箱的原理,以及會出現(xiàn)的一些陷阱已經(jīng)性能等。如有錯誤還請大家及時指出~

本文已同步至 GitHub/Gitee/公眾號,感興趣的同學幫忙點波關(guān)注~

問題:

基本數(shù)據(jù)類型與封裝數(shù)據(jù)類型有哪些區(qū)別?

什么是裝箱?什么是拆箱?

裝箱和拆箱都是如何實現(xiàn)的?

使用時需要注意哪些問題?

1.基礎(chǔ)知識回顧

Java把內(nèi)存劃分成兩種:一種是棧內(nèi)存,另一種是堆內(nèi)存。

int是基本類型,直接存數(shù)值;而 Integer是類,產(chǎn)生對象時用一個引用指向這個對象。

封裝類位于java.lang包中。

封裝類是引用傳遞而基本類型是值傳遞

基本類型的變量和對象的引用變量都是在函數(shù)的棧內(nèi)存中分配 ,而實際的對象是在存儲堆內(nèi)存中

1.1 基本數(shù)據(jù)類型和封裝類型的區(qū)別

我們來看下他們之間有哪些區(qū)別:

八種基本數(shù)據(jù)類型分別是:byte、char、boolean、int、short、float、double、long;
對應(yīng)的封裝類型分別是:Byte、Character、Boolean、Integer、Short、Float、Double、Long。

基本類型 封裝類型 字節(jié)長度 默認值
boolean Boolean 1 false
byte Byte 1 0
char Character 2 u0000
short Short 2 0
int integer 4 0
long Long 8 0l或0L
float Float 4 0.0f或0.0F
double Double 8 0.0
2. "==" 和 "equal()" 方法

在鞏固了上面的基礎(chǔ)知識點之后,我們再來看下另外的一個知識點 "=="和"equal()" 這兩個判斷符在比較基本數(shù)據(jù)類型和封裝類型的時候會做的一些事情。

" == ":比較的是基本數(shù)據(jù)類型,比較的是它們的值

"equals()": 比較的是引用數(shù)據(jù)類型,根據(jù)不同的數(shù)據(jù)類型調(diào)用不同的equals方法。在特殊情況下可以重寫equals方法。

a==b并不能判斷a等于b,而是判斷是否為同一個Object。如果我們要判斷他們的值怎么做呢?用equal或者Objects.equals()(JDK1.7之后新加 的語法)

Objects.equals有什么好處呢?

如果用a.equals(b) 如果a是null 的話,還會拋出空指針異常。但是用Objects.equals就沒有問題。因此我們在使用引用類型的時候需要注意,當我們在賦值的時候,兩個變量都是引用同一個Object。

我們以 int與Integer 作為例子,看下"=="和"equal()"方法:

1)基本型和封裝類型進行"=="運算符的比較,封裝類型將會自動拆箱變?yōu)榛拘秃笤龠M行比較,因此Integer(0)會自動拆箱為int類型再進行比較。

2)兩個Integer類型進行"=="比較,如果其值在-128至127,那么返回true,否則返回false, 這跟Integer.valueOf()的緩沖對象有關(guān),后面會說。

3)兩個封裝類型進行equals()比較,首先equals()會比較類型,如果類型相同,則繼續(xù)比較值,如果值也相同,返回true。

4)基本型封裝類型調(diào)用equals(),但是參數(shù)是基本類型,這時候,先會進行自動裝箱,基本型轉(zhuǎn)換為其封裝類型,再進行3中的比較。

3.什么是裝箱和拆箱

基本數(shù)據(jù)(Primitive)類型的自動裝箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0開始提供的功能。Java語言規(guī)范中說道:在許多情況下包裝與解包裝是由編譯器自行完成的(在這種情況下包裝稱為裝箱,解包裝稱為拆箱)。
通俗的理解:裝箱:基本類型轉(zhuǎn)換成封裝類型, 拆箱:封裝類型轉(zhuǎn)換成基本類型 這么一個過程。在上面有介紹八種基本類型和對應(yīng)的封裝類型。下面以Integer與int之間的轉(zhuǎn)換作為理解:

3.1 自動裝箱(Autoboxing)
Integer a = 2; //Boxing

簡單的理解:將2裝在一個箱子里,這個箱子的類型是Integer 。箱子這里面裝的數(shù)值就是2,我們就完成了一次裝箱操作。并把a指向2這個箱子。

Integer b = new Integer(2);//Boxing

顯示裝箱。生成一個新的箱子 new Integer(); 并且這個箱子的值為2.而且讓b指向這個箱子。

3.2 拆箱(Unboxing)

故名思議就是將對象重新轉(zhuǎn)化為基本數(shù)據(jù)類型

int v = a.intValue(); //Unboxing

簡單的理解:將里面int的值取出來。拆箱有個很典型的用法就是在進行運算的時候:因為對象時不能直接進行運算的,而是要轉(zhuǎn)化為基本數(shù)據(jù)類型后才能進行加減乘除。

例如:

Integer c = 5;
System.out.print(c--);//進行計算時隱含的有自動拆箱
4. 裝箱拆箱結(jié)合源碼分析

通過第四點我們知道裝箱拆箱的基本概念知識,下面我們同樣以Integer 為例,進入源碼里面看看里面的乾坤。

我們首先看下Integer的大小。

4.1 Integer 大小

可以看出,其定義了Integer的最大值為2^31-1,最小值為-2^31。Integer的基本數(shù)據(jù)類型為int。

4.2 Integer中的valueOf()方法

再來看看Integer中的valueOf()方法。

可以看出valueOf()方法是個靜態(tài)方法。當傳進來的變量值在一個區(qū)間之內(nèi),直接用IntegerCache.cache[]數(shù)組里面的數(shù)返回,否則new一個新對象。

接著我們來看看IntegerCache類。其實也是會出現(xiàn)坑的一個地方。

4.3 其中存在的陷阱

接著來說下Integer這兒的一個坑,也是比較有意思的地方。

初始化Integer后,IntegerCache會緩存[-128,127]之間的數(shù)據(jù),這個區(qū)間的上限可以配置,取決于java.lang.Integer.IntegerCache.high這個屬性,這個屬性在VM參數(shù)里為-XX:AutoBoxCacheMax=2000進行設(shè)置調(diào)整或者VM里設(shè)置-Djava.lang.Integer.IntegerCache.high=2000。所以Integer在初始化完成后會緩存[-128,max]之間的數(shù)據(jù)。cache屬于常量,存放在java的方法區(qū)中。

同樣,在Long,Byte,Short,我們也可以看到緩存,其緩存數(shù)據(jù)長度均是-128到127。這里不做展開。

另外其他陷阱:
如:

System.out.println(Integer.valueOf(null));

Integer對象的值可以為null,所以編譯器檢查時不會出現(xiàn)檢查時異常,但是在轉(zhuǎn)換成int的時候就會拋出空指針異常。

4. 例題分析

我們通過幾個經(jīng)典的問題,來看看大家到底理解了裝箱與拆箱的知識點沒。

new Integer(5) == 5?

new Integer(5) == new Integer(5) ?

Integer.valueOf(5) == Integer.valueOf(5)?

Integer.valueOf(5).intValue() == 5?

new Integer(5).equals(new Integer(5))?

4.1 問題一:new Integer(5) == 5?

答案:true。 等號的左邊是一個Object右邊是一個數(shù)值,Object和數(shù)值怎么會相等的呢?Java的編譯器很聰明,它會自己去做裝箱和拆箱的操作。這邊它將new Integer(5)做的是Unboxing,它會里面的value取出來,這時候發(fā)現(xiàn)取出來的5等于右邊,所以就為true。

4.2 問題二:new Integer(5) == new Integer(5) ?

答案:false。 new Integer(5) 就是新建一個箱子,這個箱子的值就是5。 == 是判斷這兩個箱子是不是同一個箱子,不是說里面的值是不是一樣.所以是false。因為他們不是同一個箱子。

4.3 問題三:Integer.valueOf(5) == Integer.valueOf(5)?

答案: true。 Integer.valueOf(5)它會返回一個箱子給我們,箱子里面的值是5。但是在返回這個箱子給我們的時候,可能會新建一個新的箱子給我們,也可能會使用現(xiàn)有的一個箱子給我們。所以Integer.valueOf(5) == Integer.valueOf(5)。什么情況下才會相等呢?只有當系統(tǒng)已經(jīng)將2這個箱子建立好了,并且緩存起來的情況下。會把箱子的引用同時發(fā)給等號的左邊與右邊。這樣的情況,他們才會互相相等。Integer.valueOf() 是系統(tǒng)給我們分配的一個箱子,我們發(fā)現(xiàn),每次調(diào)我們的箱子時候,系統(tǒng)都給了同一個箱子。這個我們的 Integer.valueOf(5) == Integer.valueOf(5)

但是: 可能為false。我們在上面介紹過,在low和high之間,它會返回一個系統(tǒng)已經(jīng)生產(chǎn)的cache,否則它會生產(chǎn)一個新的出來??丛创a可以看到low = -128 high = 127。所以當它的值超過了區(qū)間后,它就會返回新的箱子,所以就會為false。

我們不用5改用200試一試。

Integer.valueOf(200) == Integer.valueOf(200)

答案:false。 說明系統(tǒng)對小的數(shù)字會使用系統(tǒng)分配的箱子,對于大的數(shù)字,系統(tǒng)會重新new一個箱子。面試的時候,可以回答,他們可能相等,也可能不相等。是有系統(tǒng)決定的。

4.4 問題四:Integer.valueOf(5).intValue() == 5?

答案: true。 intValue()做了一個拆箱的操作,將里面的值5取出來,值5等于5,所以是true。

4.5 問題五:new Integer(5).equals(new Integer(5))?

答案:true。 這里我們沒有用==而是用equals,equals判斷相等是判斷里面的值是不是相等,而不是判斷這個箱子是不是同一個,所以我們的答案是true。我們來看看equals的源碼。判斷里面的值是不是相等。

打印結(jié)果:

文末

本章節(jié)主要簡單介紹了自動裝箱與拆箱的相關(guān)知識,希望對大家有所幫助~
今后我會在每張文章開頭增加 每章一點正能量 ,文末增加5個編程相關(guān)的英語單詞 學點英語。希望大家和我一樣每天都能積極向上,一起學習一同進步!

學點英語

AWT(Abstract Window Toolkit)抽象窗口工具

API(Application Programming Interface)應(yīng)用程序接口

AOP Aspect Oriented Programming(面向切面編程),可以 通過預編譯方式和運行期動態(tài)代理實現(xiàn)在不修改源代碼的情況下給程序動態(tài)統(tǒng)一 添加功能的一種技術(shù)。

BMP Bean-Managed Persistent(Bean管理的持久性),EJB中由 Bean自己負責持久性管理的方法,Bean的內(nèi)容的同步(保存)需要自己編寫代碼 實現(xiàn)。

I18N internationalization(國際化),這個單詞的長度是20,然后取 其首尾字母,中間省略的字母剛好18個。

歡迎關(guān)注公眾號:Coder編程
獲取最新原創(chuàng)技術(shù)文章和相關(guān)免費學習資料,隨時隨地學習技術(shù)知識!

參考文章:

https://blog.csdn.net/u013309...

https://blog.csdn.net/jairusc...

https://www.cnblogs.com/dolph...

推薦閱讀

一篇帶你讀懂TCP之“滑動窗口”協(xié)議

帶你了解數(shù)據(jù)庫中JOIN的用法

帶你了解數(shù)據(jù)庫中g(shù)roup by的用法

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74332.html

相關(guān)文章

  • 14.java 基本數(shù)據(jù)類型的包裝類

    摘要:但是基本數(shù)據(jù)類型不是對象,不具備對象的特性不攜帶屬性沒有方法可調(diào)用。自動裝箱即直接賦值將會比使用構(gòu)造方法的方式節(jié)省一塊堆內(nèi)存空間,并自動入對象池。而手動裝箱使用構(gòu)造方法會產(chǎn)生兩塊堆內(nèi)存,而且不會保存在對象池中。 概念 java在設(shè)計之初,有一個基本原則:一切皆對象。但是基本數(shù)據(jù)類型不是對象,不具備對象的特性——不攜帶屬性、沒有方法可調(diào)用。為了解決此類問題,Java為每種基本數(shù)據(jù)類型分別...

    yanbingyun1990 評論0 收藏0
  • Hollis原創(chuàng)|不了解這12個語法糖,別說你會Java

    摘要:但其實,虛擬機并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...

    番茄西紅柿 評論0 收藏0
  • Hollis原創(chuàng)|不了解這12個語法糖,別說你會Java

    摘要:但其實,虛擬機并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...

    番茄西紅柿 評論0 收藏0
  • Hollis原創(chuàng)|不了解這12個語法糖,別說你會Java

    摘要:但其實,虛擬機并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...

    yy13818512006 評論0 收藏0
  • 【??途W(wǎng)】-- 日日刷(第二天)

    摘要:以字符串形式返回指定的請求頭的值。返回一個數(shù)組,包含客戶端發(fā)送該請求的所有的對象。生命的河流就這樣,不舍晝夜,奔向它理想的海洋。 昨天加班 日日刷廢了,這是個很不好的習慣補上昨日份的 ========================================================================= 1、下面哪個不是Java語言的關(guān)鍵字(B) A def...

    warkiz 評論0 收藏0

發(fā)表評論

0條評論

FullStackDeveloper

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<