Java的八種基本數(shù)據(jù)類型
基本數(shù)據(jù)類型
Java語言提供了八種基本類型。
基本數(shù)據(jù)類型:數(shù)值型、字符型、布爾型。
數(shù)值型:整數(shù)型byte、short、int、long
浮點(diǎn)型:float、double


byte:
byte數(shù)據(jù)類型是8位、有符號的,以二進(jìn)制補(bǔ)碼表示的整數(shù);(256個(gè)數(shù)字),占1字節(jié)
最小值是-128(-2^7);
最大值是127(2^7-1);
默認(rèn)值是0;
byte類型用在大型數(shù)組中節(jié)約空間,主要代替整數(shù),因?yàn)閎yte變量占用的空間只有int類型的四分之一;
short:
short數(shù)據(jù)類型是16位、有符號的以二進(jìn)制補(bǔ)碼表示的整數(shù),占2字節(jié)
最小值是-32768(-2^15);
最大值是32767(2^15 - 1);
Short數(shù)據(jù)類型也可以像byte那樣節(jié)省空間。一個(gè)short變量是int型變量所占空間的二分之一;
默認(rèn)值是0;
int:
int數(shù)據(jù)類型是32位、有符號的以二進(jìn)制補(bǔ)碼表示的整數(shù);占4字節(jié)
最小值是-2,147,483,648(-2^31);
最大值是2,147,485,647(2^31 - 1);
一般地整型變量默認(rèn)為int類型;
默認(rèn)值是0;
long:
long數(shù)據(jù)類型是64位、有符號的以二進(jìn)制補(bǔ)碼表示的整數(shù);占8字節(jié)
最小值是-9,223,372,036,854,775,808(-2^63);
最大值是9,223,372,036,854,775,807(2^63 -1);
這種類型主要使用在需要比較大整數(shù)的系統(tǒng)上;
默認(rèn)值是0L;
這里需要注意的是在定義long時(shí),數(shù)值大于int的規(guī)定最大值會受檢報(bào)錯,需要在數(shù)字的尾部加上l。

空間占用
在實(shí)際操作中,空間大小又分為兩類:
1、理論規(guī)定大小。
2、JVM的真實(shí)大小。
開辟內(nèi)存空間發(fā)生在變量定義時(shí),且與儲存的內(nèi)容無關(guān),只與數(shù)據(jù)類型有關(guān)。不同的數(shù)據(jù)類型存同樣的數(shù)據(jù),所占用的內(nèi)存是不同的。
這是理論上的圖示:

但是在JVM在字節(jié)碼層面上支持的整數(shù)類型確實(shí)只有int和long,所有比int小的整數(shù)類型都會被提升為int來運(yùn)算。
(但是在JVM的數(shù)組byte[],和short[]中,每個(gè)元素是真正的1字節(jié)和2字節(jié),我們繼續(xù)往下看)

所以在Java中byte,short并不會起到提高效率的作用,兩者和int的效率基本是一樣的。(但數(shù)組byte[]、short[]會起到提高效率的作用)。
java虛擬機(jī)對byte、char和short的處理方式(轉(zhuǎn)載)
? ? ? ? java字節(jié)碼中的大部分指令都沒有支持整數(shù)類型byte、char和short,甚至沒有任何指令支持boolean類型,編譯器會在編譯期或者運(yùn)行期將byte和short類型的數(shù)據(jù)帶符號擴(kuò)展為相應(yīng)的int類型的數(shù)據(jù),將boolean和char類型數(shù)據(jù)零位擴(kuò)展為相應(yīng)的int類型數(shù)據(jù),與之類型,在處理boolean、byte、short和char類型的數(shù)組時(shí),也會轉(zhuǎn)換為使用對應(yīng)的int類型的字節(jié)碼指令來處理,因此,大多數(shù)對于boolean、byte、short和char類型數(shù)據(jù)的操作,實(shí)際上都是使用相應(yīng)的int類型作為運(yùn)算類型
多余定義變量會浪費(fèi)空間
而只有數(shù)組byte[]才會是真正是1字節(jié),short[]是2字節(jié)。
此外,定義變量而不使用,是一種浪費(fèi)空間的行為,Java的編譯器會建議你刪掉沒有使用的變量

目前,我們計(jì)算機(jī)的內(nèi)存越來越多。對于常規(guī)的定義大多使用int方法,從便利上已滿足需要。
但在一些大型程序如游戲的開發(fā)中,為了追求極致而節(jié)省空間。就會采用相近合適的數(shù)據(jù)類型來存儲數(shù)據(jù)。
下面,我們來看一看不同數(shù)據(jù)類型的變量在創(chuàng)建時(shí)的內(nèi)存使用情況。
運(yùn)行時(shí)觀看內(nèi)存情況
注意:byte類型雖然在語義(邏輯)上是占用1字節(jié),但實(shí)際上,JVM中是將其當(dāng)做int看的,也就是事實(shí)上是占用了32位,4字節(jié)的,所以其運(yùn)算效率和int沒區(qū)別。
之所以要有byte/short類型,一是因?yàn)槟承┑胤揭鞔_使用這些范圍類型,
二是,在byte[]數(shù)組中,JVM存儲的則是真的1字節(jié),short[]2字節(jié)。(但也有的JVM其byte[]數(shù)組也是4字節(jié)1位)
這種規(guī)定與真實(shí)的差異是由JVM翻譯所造成的。
下面,我們使用Java庫的方法來查看內(nèi)存的使用。
為了使變化更明顯,我們定義了一個(gè)較大的二維數(shù)組來觀看:
用int來定義二維數(shù)組:

使用內(nèi)存5833KB
由byte數(shù)據(jù)類型來創(chuàng)建二維數(shù)組:

使用內(nèi)存2582KB
由于,程序在啟動時(shí),還有其他的加載項(xiàng)。所以byte與int并沒有呈現(xiàn)嚴(yán)格的4倍關(guān)系。
以上,就是不同數(shù)據(jù)類型的數(shù)組開辟內(nèi)存空間所帶來的差異。(考慮到JVM,以上情況僅適用于數(shù)組)
以及存儲數(shù)據(jù)并不會帶來空間上的變化。

整型間的數(shù)字類型轉(zhuǎn)換:
Java中數(shù)據(jù)類型轉(zhuǎn)換分為自動類型轉(zhuǎn)換和強(qiáng)制類型轉(zhuǎn)換
什么叫做自動轉(zhuǎn)換?
自動轉(zhuǎn)換
小水杯向大水杯倒,不需要進(jìn)行額外進(jìn)行操作
強(qiáng)制類型轉(zhuǎn)換
從大類型向小類型,可能會溢出出現(xiàn)錯誤。
代碼中會提示錯誤,所以要加上強(qiáng)制類型轉(zhuǎn)換
byte b = 127; int i = b;//自動轉(zhuǎn)換
b = (byte)i;//強(qiáng)制轉(zhuǎn)換有可能導(dǎo)致精度丟失。
強(qiáng)制類型轉(zhuǎn)換精度丟失如圖所示:


我們知道byte的范圍是 -128~127
a=128超出了byte正數(shù)的范圍,所以b以-128為起始重新開始相加
利用這個(gè)特點(diǎn),在一定情況下可以利用byte反推出int的值(雖然應(yīng)該用不到)
也可以從二進(jìn)制數(shù)來區(qū)分?jǐn)?shù)據(jù)類型的大小:

這里boolean類型雖然只有一個(gè)二進(jìn)制數(shù),但仍然和byte一樣,占一個(gè)字節(jié)。(JVM會將boolean翻譯成int類型,會占用4個(gè)字節(jié)。byte和short上面已經(jīng)提到,char稍后討論)
浮點(diǎn)型
float
float屬于Java中的浮點(diǎn)型,也叫單精度浮點(diǎn)型,長度為4字節(jié)32bit,變量初始化默認(rèn)值0.0f,包裝類Float
double
double屬于Java中的浮點(diǎn)型,也叫雙精度浮點(diǎn)型,長度為8字節(jié)64bit,變量初始化默認(rèn)值0.0d,包裝類Double
當(dāng)整型轉(zhuǎn)向浮點(diǎn)型時(shí)要進(jìn)行強(qiáng)制類型轉(zhuǎn)換
int a = 10;
float b = 10.1f;
a = (int) b;
目前double的使用比較頻繁。
字符型
char類型是一個(gè)單一的16位Unicode字符;用 ‘’表示一個(gè)字符。java 內(nèi)部使用Unicode字符集,它有一些轉(zhuǎn)義字符 ?,2字節(jié)
最小值是’\u0000’(即為0);
最大值是’\uffff’(即為65,535);可以當(dāng)整數(shù)來用,它的每一個(gè)字符都對應(yīng)一個(gè)數(shù)字
字符型相加會按順序執(zhí)行,強(qiáng)制轉(zhuǎn)換成int類型會輸出對應(yīng)的ascii碼

同樣,漢字也可以通過字符相加進(jìn)行變動。以部首和筆畫為順序


需要注意的是,char類型在虛擬機(jī)中也是轉(zhuǎn)換為int類型。
boolean類型
boolean數(shù)據(jù)類型表示一位的信息;
只有兩個(gè)取值:true和false;
這種類型只作為一種標(biāo)志來記錄true/false情況;
默認(rèn)值是false;
boolean的大?。ㄞD(zhuǎn)載)
1、1個(gè)bit
理由是boolean類型的值只有true和false兩種邏輯值,在編譯后會使用1和0來表示,這兩個(gè)數(shù)在內(nèi)存中只需要1位(bit)即可存儲,位是計(jì)算機(jī)最小的存儲單位。
2、1個(gè)字節(jié)
理由是雖然編譯后1和0只需占用1位空間,但計(jì)算機(jī)處理數(shù)據(jù)的最小單位是1個(gè)字節(jié),1個(gè)字節(jié)等于8位,實(shí)際存儲的空間是:用1個(gè)字節(jié)的最低位存儲,其他7位用0填補(bǔ),如果值是true的話則存儲的二進(jìn)制為:0000 0001,如果是false的話則存儲的二進(jìn)制為:0000 0000。
3、4個(gè)字節(jié)
理由來源是《Java虛擬機(jī)規(guī)范》一書中的描述:“雖然定義了boolean這種數(shù)據(jù)類型,但是只對它提供了非常有限的支持。在Java虛擬機(jī)中沒有任何供boolean值專用的字節(jié)碼指令,Java語言表達(dá)式所操作的boolean值,在編譯之后都使用Java虛擬機(jī)中的int數(shù)據(jù)類型來代替,而boolean數(shù)組將會被編碼成Java虛擬機(jī)的byte數(shù)組,每個(gè)元素boolean元素占8位”。這樣我們可以得出boolean類型占了單獨(dú)使用是4個(gè)字節(jié),在數(shù)組中又是1個(gè)字節(jié)。
顯然第三條是更準(zhǔn)確的說法,那虛擬機(jī)為什么要用int來代替boolean呢?為什么不用byte或short,這樣不是更節(jié)省內(nèi)存空間嗎。大多數(shù)人都會很自然的這樣去想,我同樣也有這個(gè)疑問,經(jīng)過查閱資料發(fā)現(xiàn),使用int的原因是,對于當(dāng)下32位的處理器(CPU)來說,一次處理數(shù)據(jù)是32位(這里不是指的是32/64位系統(tǒng),而是指CPU硬件層面),具有高效存取的特點(diǎn)。
可以看出,boolean類型沒有給出精確的定義,《Java虛擬機(jī)規(guī)范》給出了4個(gè)字節(jié),和boolean數(shù)組1個(gè)字節(jié)的定義,具體還要看虛擬機(jī)實(shí)現(xiàn)是否按照規(guī)范來,所以1個(gè)字節(jié)、4個(gè)字節(jié)都是有可能的。這其實(shí)是運(yùn)算效率和存儲空間之間的博弈,兩者都非常的重要。
以double為例由控制臺輸出數(shù)據(jù)類型大小
