文章大綱
1.介紹基本數(shù)據(jù)類型的相關(guān)特點(diǎn)
2.數(shù)據(jù)類型注意事項(xiàng)
3.相關(guān)考題解析
基本數(shù)據(jù)類型的相關(guān)特點(diǎn)
一張圖概括全部的數(shù)據(jù)類型纹蝴,主要的研究的是上面的基本數(shù)據(jù)類型海铆,下面再以各種數(shù)據(jù)類型所占字節(jié)數(shù)大小再重新分類一遍幫助記憶:
boolean
再強(qiáng)調(diào)一遍:只有true和false
byte
1位(是數(shù)據(jù)的最小單位) 迹恐,但是大多數(shù)情況下數(shù)據(jù)最小單位為1個(gè)字節(jié)(byte)因?yàn)? bit 的信息量太少了。要表示一個(gè)有用的信息卧斟,需要好幾個(gè)bit一起表示殴边。我們的其他基本數(shù)據(jù)類型都是由byte組成。
那么講到字節(jié)就稍微提一下字符編碼 ASCII珍语,Unicode和UTF-8之間的概念和由來锤岸。
ASCII是上個(gè)世紀(jì)60年代,美國制定了一套字符編碼板乙,對英語字符與二進(jìn)制位之間的關(guān)系是偷,做了統(tǒng)一規(guī)定。這被稱為ASCII碼募逞,一直沿用至今蛋铆。它由一個(gè)字節(jié)組成也就是8位,一共表示128個(gè)字符放接。因?yàn)槲鞣降挠⑽木?6個(gè)字母刺啦,再加上大寫字母各種其他的符號。128也是夠用的了(因?yàn)榈谝晃灰?guī)定為0 所以就只表示128個(gè)字符啦)
但是西方國家還有很多纠脾,比如德國法國等玛瘸,他們的語言也需要一套字符編碼,不過都是在一個(gè)字節(jié)之內(nèi)就能解決的事情苟蹈。每個(gè)國家就定義了自己的一套標(biāo)準(zhǔn)
其中最常見的ISO/IEC 8859-1就是法語捧韵,芬蘭語所用的西歐字符集
但是中文就比較復(fù)雜,有10萬多個(gè)漢字汉操,那么這意義著要更多的字節(jié)去表示這些漢字
然后同一段字節(jié)流到了不同的國家可能因?yàn)闃?biāo)準(zhǔn)不同再来,導(dǎo)致會(huì)變出各種奇怪的符號,也就是不統(tǒng)一了。
那么最終還是要統(tǒng)一的芒篷,就出現(xiàn)了unicode全世界每個(gè)不同語言的不同字符都統(tǒng)一編碼搜变,全球通行。默認(rèn)unicode采用2個(gè)字節(jié)针炉,先講這么多挠他。不要跑題了。
char
有一道面試題:java中的一個(gè)char變量能否表示一個(gè)漢字篡帕,為什么殖侵?
當(dāng)時(shí)我是有點(diǎn)懵逼的,到底可以還是不可以呢镰烧?(希望有大神能詳細(xì)解答一下)
我查了一下正確答案是可以的 unicode是2個(gè)字節(jié) (16位)可以表示漢字拢军。
整型常量和浮點(diǎn)型常量
補(bǔ)充一下相關(guān)字節(jié)和位的知識:
1個(gè)字節(jié)=8位 8位代表256個(gè)數(shù)字 第一位符號位 0 正 1負(fù) 其余7位代表數(shù)字 2^7=127 因?yàn)橹挥幸粋€(gè)0
當(dāng)1 0000000時(shí)表示-128 所以 byte為 -128-127 其他類型以此類推
問題1:在不同的位數(shù)的操作系統(tǒng)上 是否基本數(shù)據(jù)類型所表示的范圍相同呢?
答:在C/C++上是不同的怔鳖,但是在java上是相同的茉唉。
32位編譯器:
char :1個(gè)字節(jié)
char*(即指針變量): 4個(gè)字節(jié)(32位的尋址空間是2^32, 即32個(gè)bit,也就是4個(gè)字節(jié)结执。同理64位編譯器)
short int : 2個(gè)字節(jié)
int: 4個(gè)字節(jié)
unsigned int : 4個(gè)字節(jié)
float: 4個(gè)字節(jié)
double: 8個(gè)字節(jié)
long: 4個(gè)字節(jié)
long long: 8個(gè)字節(jié)
unsigned long: 4個(gè)字節(jié)
64位編譯器:
char :1個(gè)字節(jié)
char*(即指針變量): 8個(gè)字節(jié)
short int : 2個(gè)字節(jié)
int: 4個(gè)字節(jié)
unsigned int : 4個(gè)字節(jié)
float: 4個(gè)字節(jié)
double: 8個(gè)字節(jié)
long: 8個(gè)字節(jié)
long long: 8個(gè)字節(jié)
unsigned long: 8個(gè)字節(jié)
以上占用字節(jié)數(shù)其實(shí)是針對c/c++語言而言的度陆,對于java來說由于其JVM具有跨平臺(tái)性因此java在32位和64位機(jī)下基本數(shù)據(jù)類型占字節(jié)數(shù)是一致的(這樣才能達(dá)到跨平臺(tái)通信)。
問題2:
如果是在不同位數(shù)的jvm上呢献幔?32位的jvm和64位的jvm是否表示范圍相同懂傀?
看到這個(gè)問題的我,是一臉懵逼的蜡感。
個(gè)人感覺應(yīng)該不同吧鸿竖,畢竟java是跑在jvm上的所以和操作系統(tǒng)的位數(shù)沒關(guān)。那么jvm的位數(shù)應(yīng)該就有關(guān)了吧铸敏。(希望有大神能解答)
數(shù)據(jù)類型注意事項(xiàng)
1.自動(dòng)類型轉(zhuǎn)換
本數(shù)據(jù)類型中缚忧,布爾類型boolean占有一個(gè)字節(jié),由于其本身所代碼的特殊含義杈笔,boolean類型與其他基本類型不能進(jìn)行類型的轉(zhuǎn)換(既不能進(jìn)行自動(dòng)類型的提升闪水,也不能強(qiáng)制類型轉(zhuǎn)換), 否則蒙具,將編譯出錯(cuò)球榆。
轉(zhuǎn)換圖的幾點(diǎn)說明:
1.紅色的int和double代表,在Java中禁筏,整數(shù)類型(byte/short/int/long)中持钉,對于未聲明數(shù)據(jù)類型的整形,其默認(rèn)類型為int型篱昔。在浮點(diǎn)類型(float/double)中每强,對于未聲明數(shù)據(jù)類型的浮點(diǎn)型始腾,默認(rèn)為double型。
2.上下兩個(gè)大的藍(lán)色箭頭表示空执,從低到高類型自動(dòng)轉(zhuǎn)換浪箭,高到低需要強(qiáng)制轉(zhuǎn)換,原因很簡單辨绊,高位表示的范圍大奶栖,低位表示的范圍小。
3.在byte char short之間的爆炸符號,代表的意思雖然類型從小到大自動(dòng)轉(zhuǎn)換,但是byte不能轉(zhuǎn)成char,char也不能轉(zhuǎn)成short。因?yàn)閎yte和short是是數(shù)值型的變量,char字符型的變量蕴茴。數(shù)值型變量有符號(第一位)而在char中則無正負(fù)之分。byte轉(zhuǎn)short自然就是可以的了。
例題引出問題:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
long a = 10000000000; //編譯出錯(cuò): The literal 10000000000 of type int is out of range
long b = 10000000000L; //編譯正確
int c = 1000;
long d = c;
float e = 1.5F;
double f = e;
}
}
a錯(cuò)的原因是,整型數(shù)默認(rèn)為int型,而這個(gè)數(shù)字大小已經(jīng)超過了int的范圍宣虾,又沒有在后面加L表示為long所以就錯(cuò)了惯裕。b就是很好的修正例子。
例題引出問題2:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
byte p = 3; // 編譯正確:int到byte編譯過程中發(fā)生隱式類型轉(zhuǎn)換
int a = 3;
byte b = a; // 編譯出錯(cuò):cannot convert from int to byte
byte c = (byte) a; // 編譯正確
float d = (float) 4.0;
}
}
p正確的原因是首先3是一個(gè)int型的數(shù)值绣硝,并且沒有超過int的范圍蜻势,其次再看這個(gè)p的類型為byte,在進(jìn)行隱式轉(zhuǎn)換沒有溢出鹉胖,包含在byte的范圍中握玛。所以正確。
b錯(cuò)誤的原因是a是int型的3甫菠,雖然這個(gè)大小也在byte的范圍中挠铲。但是在編譯過程中,b被賦值的是變量a寂诱,事先不知道是否a的大小能在byte范圍中拂苹。保險(xiǎn)起見編譯出錯(cuò)。
c正確的原因是加了強(qiáng)制轉(zhuǎn)換
d也是痰洒,默認(rèn)4.0為double型瓢棒,然后強(qiáng)制轉(zhuǎn)換當(dāng)然就正確了。可是為什么不像p一樣丘喻,做隱式轉(zhuǎn)換呢(求大神詳解)脯宿。好像是浮點(diǎn)存在精度問題,而整型沒有泉粉。
例題引出問題3:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
int a = 233;
byte b = (byte) a;
System.out.println("b:" + b); // 輸出:-23
}
}
看到這里的b輸出是一個(gè)負(fù)數(shù)连霉,那么這里的原因是因?yàn)椋吹絠nt的a=233這個(gè)是超過了byte的范圍了。然后a強(qiáng)制轉(zhuǎn)換成b窘面,我們先把a(bǔ)換成二進(jìn)制24位0 + 11101001(int為4個(gè)字節(jié) 32位) 只取最低的8位翠语,一共截取8位(byte所占用的空間大小)财边。然后因?yàn)樽罡呶粸?代表負(fù)數(shù) 所以b為-23
問題來了肌括,我們看11101001這個(gè)二進(jìn)制表示的不是-23呀,這是怎么得來的-23呢酣难?
原因是計(jì)算機(jī)中的數(shù)據(jù)運(yùn)算都是通過補(bǔ)碼來運(yùn)行的谍夭。兩個(gè)數(shù)通過各自補(bǔ)碼進(jìn)行加減運(yùn)算,得出的補(bǔ)碼結(jié)果再轉(zhuǎn)成原碼就是正確的計(jì)算結(jié)果憨募。我們看到11101001是溢出的紧索,其實(shí)是補(bǔ)碼。轉(zhuǎn)成原碼后就是-23了菜谣。第一位符號位不變珠漂,然后取反加1.、
不能對boolean類型進(jìn)行類型轉(zhuǎn)換尾膊。
不能把對象類型轉(zhuǎn)換成不相關(guān)類的對象媳危。
long a=123;//long類型 不加L默認(rèn)是int 當(dāng)數(shù)字范圍在int之內(nèi) int自動(dòng)轉(zhuǎn)long不報(bào)錯(cuò)
long b=11111111111;//報(bào)錯(cuò) 因?yàn)槌^了int的范圍又不加L
相關(guān)考題解析
1.short s1 = 1; s1 = s1 + 1;對還是錯(cuò) 為什么? short s1 = 1; s1 +=1;對還是錯(cuò) 為什么?
2.int 和 Integer 有什么區(qū)別?
3.我們能將 int 強(qiáng)制轉(zhuǎn)換為 byte 類型的變量嗎冈敛?如果該值大于 byte 類型的范圍待笑,將會(huì)出現(xiàn)什么現(xiàn)象?
4.a = a + b 與 a += b 的區(qū)別
存在使i + 1 < i的數(shù)嗎()
答案:存在
解析:如果i為int型抓谴,那么當(dāng)i為int能表示的最大整數(shù)時(shí)暮蹂,i+1就溢出變成負(fù)數(shù)了,此時(shí)不就<i了嗎癌压。
擴(kuò)展:存在使i > j || i <= j不成立的數(shù)嗎()
答案:存在
解析:比如Double.NaN或Float.NaN0.6332的數(shù)據(jù)類型是()
A float B double C Float D Double
答案:B
解析:默認(rèn)為double型仰泻,如果為float型需要加上f顯示說明,即0.6332f
參考文獻(xiàn):
Java面試題--數(shù)據(jù)類型和java基礎(chǔ)
Java總結(jié)篇系列:類型轉(zhuǎn)換/造型