Java八大基本數(shù)據(jù)類(lèi)型
1.介紹
Java語(yǔ)言提供了8種基本數(shù)據(jù)類(lèi)型豆赏。分別是 byte挣菲、short富稻、int掷邦、long、float椭赋、double抚岗、boolean、char哪怔。
String 是對(duì)象宣蔚,不屬于基本數(shù)據(jù)類(lèi)型
8種基本數(shù)據(jù)按類(lèi)型分可以分為
- 4個(gè) 整數(shù)型:byte、short认境、int胚委、long
- 2個(gè)浮點(diǎn)型:float、double
- 1個(gè)字符類(lèi)型:char
- 1個(gè)布爾型:boolean
基本數(shù)據(jù)類(lèi)型 "==" 比較都是值叉信。
Boolean 《Java虛擬機(jī)規(guī)范》給出了4個(gè)字節(jié),但還要看虛擬機(jī)實(shí)現(xiàn)是否按照規(guī)范來(lái)亩冬,所以1個(gè)字節(jié)、4個(gè)字節(jié)都是有可能的硼身。
2硅急、拆箱和裝箱問(wèn)題
-
拆箱和裝箱
裝箱就是自動(dòng)將基本數(shù)據(jù)類(lèi)型轉(zhuǎn)換為包裝器類(lèi)型;使用Integer.valueOf
方法佳遂。
拆箱就是自動(dòng)將包裝器類(lèi)型轉(zhuǎn)換為基本數(shù)據(jù)類(lèi)型营袜;使用Integer.intValue
方法。
Integer total = 99;
//執(zhí)行上面那句代碼的時(shí)候丑罪,系統(tǒng)為我們執(zhí)行了荚板,即自動(dòng)裝箱
Integer total = Integer.valueOf(99);
int totalprim = total;
//執(zhí)行上面那句代碼的時(shí)候凤壁,系統(tǒng)為我們執(zhí)行了,即自動(dòng)拆箱
int totalprim = total.intValue();
-
范圍問(wèn)題
通過(guò)一個(gè)問(wèn)題去引申跪另,面試經(jīng)常被問(wèn)的:
Integer i = 400;
Integer j = 400;
System.out.println(i==j); //false
Integer o = 12;
Integer k = 12;
System.out.println(o==12); //true
上面提到客扎,使用 Integer
去創(chuàng)建數(shù)據(jù),其實(shí)是一個(gè)Integer.valueOf
過(guò)程罚斗,Integer.valueOf
源碼如下:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
如果值的范圍在-128到127之間徙鱼,它就從高速緩存返回實(shí)例。
否則 new 一個(gè)Integer對(duì)象针姿。new Integer
就是一個(gè)裝箱的過(guò)程了袱吆,裝箱的過(guò)程會(huì)創(chuàng)建對(duì)應(yīng)的對(duì)象,這個(gè)會(huì)消耗內(nèi)存距淫,所以裝箱的過(guò)程會(huì)增加內(nèi)存的消耗绞绒,影響性能。
所以說(shuō)最后是i 和 j 兩個(gè)對(duì)象比較榕暇,內(nèi)存地址不一樣蓬衡,結(jié)果就是false了。
- ==的值比較問(wèn)題
int a =200;
Integer b = new Integer(200);
Integer c = 200;
System.out.println(a==b); //true
System.out.println(a==c); //true
System.out.println(b==c); //false
這也是面試經(jīng)常問(wèn)到的彤枢,在代碼中我們經(jīng)常也會(huì)用到這種判斷狰晚。
a==b,a==c
缴啡,只要和基本數(shù)據(jù)類(lèi)型(即 int)比較壁晒,Integer就會(huì)調(diào)用value.intValue()
拆箱成基本數(shù)據(jù)類(lèi)型,你也可以理解為:當(dāng)有基本數(shù)據(jù)類(lèi)型业栅,只比較值
b==c
秒咐,這兩個(gè)是永遠(yuǎn)不會(huì)相等的,拆箱裝箱只是針對(duì)基本數(shù)據(jù)類(lèi)型的比較才有碘裕,Integer并不是基本數(shù)據(jù)類(lèi)型携取,b、c兩者存放的內(nèi)存地址不一樣帮孔,所以不相等雷滋。
總結(jié):
①、無(wú)論如何你弦,Integer與new Integer不會(huì)相等惊豺。不會(huì)經(jīng)歷拆箱過(guò)程,因?yàn)樗鼈兇娣艃?nèi)存的位置不一樣禽作。
②尸昧、兩個(gè)都是非new出來(lái)的Integer,如果數(shù)在-128到127之間旷偿,則是true,否則為false烹俗。
③爆侣、兩個(gè)都是new出來(lái)的,即兩個(gè)new Integer比較幢妄,則為false兔仰。
④、int與Integer蕉鸳、new Integer()進(jìn)行==比較時(shí)乎赴,結(jié)果永遠(yuǎn)為true,因?yàn)闀?huì)把Integer自動(dòng)拆箱為int潮尝,其實(shí)就是相當(dāng)于兩個(gè)int類(lèi)型比較榕吼。
3、int 和 Integer
- Integer 繼承了Object類(lèi)勉失,是對(duì)象類(lèi)型羹蚣,有自己的屬性和方法,是 int 的包裝類(lèi)乱凿。int是java基本數(shù)據(jù)類(lèi)型顽素。
- Integer默認(rèn)值null,int默認(rèn)值 0徒蟆。
- int 可以直接做運(yùn)算胁出,Integer 不能直接運(yùn)算,拆箱轉(zhuǎn)化為int才能進(jìn)行運(yùn)算后专。
4划鸽、默認(rèn)值問(wèn)題
Java中:
- 整數(shù)的默認(rèn)類(lèi)型是 int。
- 浮點(diǎn)數(shù)默認(rèn)類(lèi)型是 double戚哎,否則需要 在后面加f、d
浮點(diǎn)數(shù)如果不加f
嫂用,默認(rèn)就是double類(lèi)型的型凳,前面再用 float修飾瀑凝,就會(huì)報(bào)錯(cuò)脆丁⌒巯可以使用兩種方法解決:
- 結(jié)尾加上
f
- 使用(float) 強(qiáng)轉(zhuǎn)
5渔期、Integer.parseInt()和Integer.valueOf()的區(qū)別
parseInt() 和 valueOf() 都是Integer 對(duì)象的方法碟刺。入?yún)⒍际且粋€(gè)String字符串端幼。
- parseInt
public static int parseInt(String s) throws NumberFormatException
將字符串參數(shù)作為帶符號(hào)十進(jìn)制整數(shù)來(lái)轉(zhuǎn)換狠持。如果無(wú)法轉(zhuǎn)換摊滔,拋出 NumberFormatException函似。
- valueOf
public static Integer valueOf(String s) throws NumberFormatException
返回初始化為指定 String 值的新的 Integer 對(duì)象槐脏,如果無(wú)法轉(zhuǎn)換,拋出 NumberFormatException撇寞。
String str = "-12";
int num = Integer.parseInt(str);
System.out.println(num); // -12
Integer num2 = Integer.valueOf(str);
System.out.println(num2); // -12
int num3 =Integer.parseInt("HaC"); //java.lang.NumberFormatException
int 與 Integer轉(zhuǎn)換:
int a=A.intValue();
Integer A=Integer.valueOf(a);
Integer派別:Integer顿天、Short堂氯、Byte、Character牌废、Long這幾個(gè)類(lèi)的valueOf方法的實(shí)現(xiàn)是類(lèi)似的咽白。
Double派別:Double、Float的valueOf方法的實(shí)現(xiàn)是類(lèi)似的鸟缕。每次都返回不同的對(duì)象晶框。
6、精度丟失問(wèn)題
byte a = 5;
int b =2;
float c = 6f;
double d =0.03;
double d2 =300.03;
System.out.println(a/b); // 2 a會(huì)轉(zhuǎn)化為int 類(lèi)型
System.out.println(b/c); // 0.33333334 b會(huì)轉(zhuǎn)化為float類(lèi)型
System.out.println(a+d+d2); // 301.05999999999995 a會(huì)轉(zhuǎn)化為double類(lèi)型,但是結(jié)果理應(yīng)是 301.06
不同類(lèi)型的數(shù)據(jù)在運(yùn)算的時(shí)候懂从,會(huì)向高精度的數(shù)據(jù)類(lèi)型轉(zhuǎn)換三妈。
其實(shí)double類(lèi)型數(shù)值的計(jì)算經(jīng)常會(huì)出現(xiàn)這種精度丟失的問(wèn)題,尤其是有小數(shù)點(diǎn)的情況下莫绣,常常會(huì)因?yàn)榫葋G失而導(dǎo)致程序出錯(cuò)畴蒲。因?yàn)橛?jì)算機(jī)是通過(guò)二進(jìn)制進(jìn)行運(yùn)算的,而計(jì)算機(jī)在表示小數(shù)的二進(jìn)制是會(huì)有精度問(wèn)題的对室。
所以我們?cè)谶\(yùn)算高精度的數(shù)據(jù)的時(shí)候模燥,可以使用 java.math.BigDecimal
類(lèi)
7、字符串與整數(shù)拼接問(wèn)題
String a = "1";
int b = 1;
int c = 2;
System.out.println(a + b + c); //112
System.out.println(b + c + a); //31
a + b + c
從左到右按順序運(yùn)算掩宜,a+b 的結(jié)果是 12 蔫骂,是一個(gè)String,然后再拼接 c牺汤,最后是 String
b + c + a
從左到右按順序運(yùn)算辽旋,b + c 的結(jié)果是 3,是一個(gè)int 檐迟,然后拼接a补胚,變成 String。
8追迟、留幾個(gè)問(wèn)題瞅瞅
1) 設(shè)有下面兩個(gè)賦值語(yǔ)句:
a = Integer.parseInt("1024");
b = Integer.valueOf("1024").intValue();
下述說(shuō)法正確的是()
A a是整數(shù)類(lèi)型變量溶其,b是整數(shù)類(lèi)對(duì)象。
B a是整數(shù)類(lèi)對(duì)象敦间,b是整數(shù)類(lèi)型變量瓶逃。
C a和b都是整數(shù)類(lèi)對(duì)象并且它們的值相等。
D a和b都是整數(shù)類(lèi)型變量并且它們的值相等廓块。
答案是 D厢绝,intValue()是把Integer對(duì)象類(lèi)型變成int的基礎(chǔ)數(shù)據(jù)類(lèi)型;
2)表達(dá)式(short)10/10.2*2運(yùn)算后結(jié)果是什么類(lèi)型带猴?
A short
B int
C double
D float
答案是 C昔汉,Java中,你如果 沒(méi)有在數(shù)字后面聲明浓利,浮點(diǎn)數(shù)默認(rèn)為double挤庇。
要注意是(short)10/10.2*2钞速,而不是(short) (10/10.2 *2),前者只是把10強(qiáng)轉(zhuǎn)為short嫡秕,又由于式子中存在浮點(diǎn)數(shù)渴语,所以會(huì)對(duì)結(jié)果值進(jìn)行一個(gè)自動(dòng)類(lèi)型的提升,浮點(diǎn)數(shù)默認(rèn)為double昆咽,所以答案是double驾凶;后者是把計(jì)算完之后值強(qiáng)轉(zhuǎn)short。
以上文章來(lái)源于HelloCoder 掷酗,作者HaC