Java的資料類型
我們知道,Java是一種 強類型 語言,類型對于Java語言來說非常的重要不言而喻,在Java中,分為 基礎資料類型 和 引用資料類型 ,其中基礎資料類型分為了 四類八種:

下面,我們來分别說一下這四類八種
整型
首先,需要說明一點,在Java的整形中不存在 unsigned 類型的數值,也就是說Java的整形都是有符号的可為正,可為負的整數
可以看出,取值範圍取決于該類型的位數,由于Java的代碼是運作在JVM中,是以該類型是獨立于機器之外存在的,與機器的關系并沒有很大,大大的提高了代碼的可移植性。
在書寫代碼的時候,我們需要注意,在我們定義一個 long 類型的變量時,一定要記得在代碼後加上大寫的 L (小寫的l在某些字型下容易被認證1,給代碼的可讀性帶來影響)。
整型預設類型
我們的整數預設類型是int類型,在我們進行計算的時候,會預設按照int類型進行計算。
byte a = 127; //right
byte b = 1; //right
byte c = a + b; // wrong
byte d = 127 + 1; //wrong
複制
編譯器報錯兩處,均是下面的這個錯誤資訊:
HelloWorld.java:7: 錯誤: 不相容的類型: 從int轉換到byte可能會有損失
byte c = a + b; // wrong
^
HelloWorld.java:9: 錯誤: 不相容的類型: 從int轉換到byte可能會有損失
byte d = 127 + 1; //wrong
複制
這是一道很常見的面試題,其中錯誤的原因有兩點:
- 編譯器可以識别常量,但是無法識别變量,常量可以在編譯期間判斷是否超出範圍,但是兩個變量相加,編譯器在編譯期間無法得知,是以會報錯。
- 編譯器在編譯期将該值作為int類型進行預編譯計算後發現超出byte的取值範圍,但是又是通過一個byte類型的變量去接收,是以就會出現可能會損失精度的異常。
這裡很好的展現了整數類型的預設計算類型就是int類型~
浮點類型
浮點型有兩種,一種是32位的float類型(單精度),一種是64位的double類型(雙精度)。
因為 double 的取值範圍更廣,精度更高,是以我們日常都是使用 double ,預設的浮點類型也是 double。
關于float和long
從上面我們可以知道float是32位的,而long是64位的,下意識的我們會認為64位的取值範圍必定要大于32位的,但事實并非如此:
float占了4個位元組,也就是32位,其中第一位是符号位,23位是尾數位,剩下的8位都是指數位,$2^{8}$為256,由于(signed)符号數的原因,也就是說,float的取值範圍大緻位于$2^{-126}$到${2^{127}}$,是要遠遠的大于long的取值範圍的。
其實,這也诠釋了另外一個浮點數問題,因為計算機是二進制的,是以無法精确的表示出浮點數,但是Java也給我們了一種解決方案,那就是我們在涉及到浮點數比較敏感的地方(比如經緯度,金錢)的時候,一定要注意使用BigDecimal 傳參為 字元串 的方式!
三個特殊的浮點數值:
1. 正無窮大(Double.POSITIVE_INFINITY)
2. 負無窮大(Double.NEGATIVE_INFINITY)
3. NAN(Double.NaN)
字元型
char關鍵字所修飾的類型是字元型,需要由單引号引起來,一個或兩個char類型的數值可以表示一個Unicode字元,我們所熟知的字元串底層資料結構正是一個字元數組常量:
/** The value is used for character storage. */
private final char value[];
複制
char類型其實是由\u+十六進制資料的組成的,最大值為\uffff(65535),最小值為\u0000(0)。
這裡需要注意一些特殊的轉義字元:
布爾型
boolean修飾的變量就是布爾型,布爾類型很簡單,隻有true false兩個值,但是這裡需要注意,和 C++不同的地方是它不能由數字0或1轉換成布爾型 。
強制類型轉換
byte a = 127; //right
byte b = 1; //right
byte c = a + b; // wrong
byte d = (byte)(a + b) // right
System.out.println(d);
複制
還是這個熟悉的例子,剛剛我們已經分析了第三種情況為什麼會報錯,這裡我們可以通過強制類型轉換來強制完成這個操作。
強制類型轉換隻發生在 位數較多 的類型(int,64位)轉為位數較少(byte,8位)的類型。
果不其然,我們将第三句注釋掉之後,代碼可以正常編譯通過,然後我們去運作的時候,發現列印的d的值如下:
-128
複制
這裡就說到了強制類型轉換會發生的一種情況,如果被轉換的數值超出目标類型的取值範圍,就會發生資料的丢失。
二進制在計算的時候,發生了超出資料範圍的進位操作,随着強制類型轉換,進位的部分被咔嚓掉,然後就發生這種情況了(熟悉原反補的同學應該明白這一點)。
var
JDK 10中推出了一種新的類型 var,猛地看起來很像 javascript 中的 var,它可以這麼玩:
var list = new ArrayList<String>();
var x = 3;
複制
乍一看,還真的和 javascript 有些像,但其實并不然,并不會影響Java是一個強類型語言的事實,它是基于局部變量推斷機制來完成的,編譯器在處理var時,先讀構造器,并将它作為變量的類型,然後将該類型寫入位元組碼當中。也就是說,該類型是無法更改的。
var a = 3;
a = [1,2,3];
複制
這樣的寫法在 javascript 中毫無問題,但是在Java中就不行。但是需要注意,var 隻能作用于帶有構造器的 局部變量 和 for循環 中。
本篇重點總結
- 資料類型 四類八種
- float取值範圍要大于long
- 強制轉換隻發生在 高位轉低位
- var 類型的原理是 局部類型推斷
原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知!