Java自動拆裝箱簡單介紹
在面試過程中,常常會有面試官問到基礎的問題的時候都會問到Java的拆裝箱,關于這個問題其實不是很難,但是如果平時進行自學的時候不是注意,就可能一臉懵逼,所以筆者就這個問題進行一些總結,共同促進!
一、拆裝箱概念
所謂的拆裝箱,就是自從JDK1.5之后,java的基本類型和引用類型之間的相互轉換。
1.1拆箱
拆箱就是把Long,Integer,Double,F(xiàn)loat 等將基本數(shù)據(jù)類型的首字母大寫的相應的引用類型轉化為基本數(shù)據(jù)類型的動作就叫拆箱。
1.2裝箱
裝箱就是把byte ,int ,short, long ,double,float,boolean,char 這些Java的基本數(shù)據(jù)類型在定義數(shù)據(jù)類型時不聲明為相對應的引用類型,在編譯器的處理下自動轉化為引用類型的動作就叫做裝箱。
二、拆裝箱的相關應用
在JDK1.5后,當我們進行基本類型和引用類型的轉換的時候就會方便:
package com.hzp.CZX;
/**
* 測試拆裝箱
* @author 夜孤寒
* @version 1.1.1
*/
public class TestDemo {
/**
* 拆裝箱JDK1.5后
*/
public static void first(){
Integer i=7;//基本類型-->引用類型
int j=i;//引用類型-->基本類型
System.out.println(j);
}
/**
* 拆裝箱JDK1.4
*/
public static void second(){
Integer i=new Integer(78);
int j=i.intValue();
System.out.println(j);
}
/**
* 測試方法
* @param args
*/
public static void main(String[] args) {
first();
second();
}
}
上面介紹了關于拆裝箱的一些基本點和使用方式,但是要使用拆裝箱的話還有一些注意點需要注意,下面將這些注意點進行一些總結。
三、注意點
首先貼一段代碼如下:
package com.ygh.CZX;
/**
* 關于java的拆裝箱范圍剖析
* @author 夜孤寒
* @version 1.1.1
*/
public class Test {
/**
* 以Integer類型為例
*/
public static void first(){
Integer i=new Integer(124);
Integer j=new Integer(124);
System.out.println(i==j);//false
Integer a1=-128;
Integer a2=-128;
System.out.println(a1==a2);//true
Integer b1=-129;
Integer b2=-129;
System.out.println(b1==b2);//false
Integer c1=127;
Integer c2=127;
System.out.println(c1==c2);//true
Integer d1=128;
Integer d2=128;
System.out.println(d1==d2);//false
}
public static void main(String[] args) {
first();
}
}
簡單解釋一下:
第一個結果為false的原因是因為創(chuàng)建了不同的對象,所以兩者不一樣;
但是第二個和第三個的結果為什么不一樣?
下面貼出關于Integer類的源碼,從源碼的角度來分析這個問題:
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
上面的代碼是說,進行自動拆裝箱的時候,是有一個范圍的,一旦超出這個范圍,那么指向的就不是同一個對象,而是返回一個新創(chuàng)建的對象了,這個范圍在Integer類中的一個內部私有類IntegerCache可以體現(xiàn)出來,源碼如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
從這里我們可以看出,范圍值為[-128,127]之間。
注意,Integer、Short、Byte、Character、Long這幾個類的valueOf方法的實現(xiàn)是類似的。
Double、Float的valueOf方法的實現(xiàn)是類似的。
總結:這些進行自動拆裝箱的基本類型的范圍如下:
1. boolean類型的值
2.所有的byte的值
3.在-128~127的short類型的值
4.在-128~127的int類型的值
5.在\ u0000~\ u00ff 之間的char類型的值
而其中double和float又有所不同,我們就以double為例子,貼出代碼討論:
package com.ygh.CZX;
/**
* 關于java的拆裝箱范圍剖析
*
* @author 夜孤寒
* @version 1.1.1
*/
public class Test {
/**
* Double
*/
public static void first() {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1 == i2);//false
System.out.println(i3 == i4);//false
}
/**
* 測試方法
*/
public static void main(String[] args) {
first();
}
}
注意為什么上面的代碼的輸出結果都是false呢?同樣的我們依舊以Double類中的valueOf方法來討論,貼出源碼就一目了然了:
/**
* Returns a {@code Double} instance representing the specified
* {@code double} value.
* If a new {@code Double} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Double(double)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param d a double value.
* @return a {@code Double} instance representing {@code d}.
* @since 1.5
*/
public static Double valueOf(double d) {
return new Double(d);
}
也就是說不管你的double是什么范圍的值,他都是給你返回一個新的對象。float同double,就不過多贅述了。
以上就是筆者對于拆裝箱的一些整理,如果讀者有不同的看法可以在評論區(qū)提出,筆者再進行修改!
希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
java8?Stream大數(shù)據(jù)量List分批處理切割方式
這篇文章主要介紹了java8?Stream大數(shù)據(jù)量List分批處理切割方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
Spring?Boot?集成Redisson實現(xiàn)分布式鎖詳細案例
這篇文章主要介紹了Spring?Boot?集成Redisson實現(xiàn)分布式鎖詳細案例,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-08-08
Spring解讀@Component和@Configuration的區(qū)別以及源碼分析
通過實例分析@Component和@Configuration注解的區(qū)別,核心在于@Configuration會通過CGLIB代理確保Bean的單例,而@Component不會,在Spring容器中,使用@Configuration注解的類會被CGLIB增強,保證了即使在同一個類中多次調用@Bean方法2024-10-10
Java 并發(fā)編程學習筆記之Synchronized底層優(yōu)化
這篇文章主要介紹了Java 并發(fā)編程學習筆記之Synchronized底層優(yōu)化的相關資料,主要包含了重量級鎖,輕量級鎖,偏向鎖和其他優(yōu)化等方面,有需要的小伙伴可以參考下2016-05-05

