1 java運算符
1.1 各個運算符一覽
| 序號 | 符號 | 名稱 | 結合性(與操作數) | 對目 | 說明 |
|---|---|---|---|---|---|
| 1 | . | 點 | 從左到右 | 雙目 | |
| 2 | () | 圓括號 | 從左到右 | ||
| 3 | [ ] | 方括號 | 從左到右 | ||
| 4 | + | 正號 | 從右到左 | 單目 | |
| 5 | - | 負號 | 從右到左 | 單目 | |
| 6 | ++ | 自增 | 從右到左 | 單目 | 前綴增,后綴增 |
| 7 | -- | 自減 | 從右到左 | 單目 | 前綴減,后綴減 |
| 8 | ~ | 按位非/取補運算 | 從右到左 | 單目 | |
| 9 | ! | 邏輯非 | 從右到左 | 單目 | “!”不可以與“=”聯(lián)用 |
| 10 | * | 乘 | 從左到右 | 雙目 | |
| 11 | / | 除 | 從左到右 | 雙目 | 整數除法: 取商的整數部分,小數部分去掉,不四舍五入 |
| 12 | % | 取余 | 從左到右 | 雙目 | |
| 13 | + | 加 | 從左到右 | 雙目 | |
| 14 | - | 減 | 從左到右 | 雙目 | |
| 15 | << | 左移位運算符 | 從左到右 | 雙目 | |
| 16 | >> | 右移位運算符 | 從左到右 | 雙目 | |
| 17 | >>> | 無符號右移位運算符 | 從左到右 | 雙目 | |
| 18 | < | 小于 | 從左到右 | 雙目 | |
| 19 | <= | 小于或等于 | 從左到右 | 雙目 | |
| 20 | > | 大于 | 從左到右 | 雙目 | |
| 21 | >= | 大于或等于 | 從左到右 | 雙目 | |
| 22 | instanceof | 確定某對象是否屬于指定的類 | 從左到右 | 雙目 | |
| 23 | == | 等于 | 從左到右 | 雙目 | |
| 24 | != | 不等于 | 從左到右 | 雙目 | |
| 25 | & | 按位與 | 從左到右 | 雙目 | |
| 26 | | | 按位或 | 從左到右 | 雙目 | |
| 27 | ^ | 按位異或 | 從左到右 | 雙目 | |
| 28 | && | 短路與 | 從左到右 | 雙目 | |
| 29 | || | 短路或 | 從左到右 | 雙目 | |
| 30 | ?: | 條件運算符 | 從右到左 | 三目 | |
| 31 | = | 賦值運算符 | 從右到左 | 雙目 | |
| 32 | += | 混合賦值運算符 | 從右到左 | 雙目 | |
| 33 | -= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 34 | *= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 35 | /= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 36 | %= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 37 | |= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 38 | ^= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 39 | <<= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 40 | >>= | 混合賦值運算符 | 從右到左 | 雙目 | |
| 41 | >>>= | 混合賦值運算符 | 從右到左 | 雙目 |
1.2 部分運算符說明
部分運算符說明:
算數運算符:+ :加法,- :減法,* :乘法,/ :除法,% :取余運算
關系運算符:
-
<:只能比較基本類型數據之間的關系,不能比較對象之間的關系; -
>: (同關系運算符<); -
<=: (同關系運算符<); -
>=: (同關系運算符<); -
==:若使用該運算符比較兩個對象的引用(變量),則實質上是比較兩個變量是否引用了相同的對象。所謂相同的對象是指,是否是在堆棧(Heap)中開辟的同一塊兒內存單元中存放的對象。
若比較兩個對象的引用(變量)所引用的對象的內容是否相同,則應該使用equals()方法,該方法的返回值類型是布爾值。需要注意的是:若用類庫中的類創(chuàng)建對象,則對象的引用調用equals()方法比較的是對象的內容;若用自定義的類來創(chuàng)建對象,則對象的引用調用equals()方法比較的是兩個引用是否引用了同一個對象,因為第二種情況equals()方法默認的是比較引用。 -
!=:(同關系運算符==)
邏輯運算符 (操作符只能是布爾類型的)&&,||,!
public class Demo {
public static void main(String[] args) {
// System.out.println((!'1'||'1')+5);//編譯錯誤
// System.out.println(!5);//編譯錯誤
// System.out.println(('1'||'1')+5);//編譯錯誤
// System.out.println(1||2);//編譯錯誤
// System.out.println(5-3||4-2);//編譯錯誤 8
System.out.println(5<3||4>3);//true 9 }
}
位運算符:&,|,^,!:不可以與=聯(lián)用,因為!是一元操作符;不可以對布爾類型的數據進行按位非運算
移位運算符(只能處理整數運算符):Char、byte、short類型,在進行移位之前,都將被轉換成int類型,移位后的結果也是int類型;移位符號右邊的操作數只截取其二進制的后5位(目的是防止因為移位操作而超出int類型的表示范圍:2的5次方是32,int類型的最大范圍是32位);對long類型進行移位,結果仍然是long類型,移位符號右邊的操作符只截取其二進制的后6位。
>> :若符號位為正,則在最高位插入0;若符號位為負,則在最高位插入1
>>>:無論正負,都在最高位插入0
1.3 java基本位操作
1.3.1 位操作符號
基本位操作符號:
-
~按位非(NOT)
公式:~n=-n-1 -
&按位與(AND) -
|按位或(OR) -
^按位異或(XOR) -
>>右移 -
>>>無符號右移 -
<<左移
前面幾個都非常簡單,主要是移位操作比較容易出錯.
首先要搞清楚參與運算的數的位數,如int的是32位,long的是64位。
如int i = 1; i的二進制原碼表示為: 00000000000000000000000000000001
long l = 1;l的二進制原碼表示為: 0000000000000000000000000000000000000000000000000000000000000001
1.3.2 原碼反碼補碼
1.3.2.1 相關定義
各個相關概念定義如下:
機器數:一個數在計算機中的二進制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號,正數為0, 負數為1
比如,十進制中的數+3,計算機字長為8位,轉換成二進制就是00000011。如果是-3,就是10000011。那么,這里的00000011和10000011就是機器數。真值:因為第一位是符號位,所以機器數的形式值就不等于真正的數值。例如上面的有符號數10000011,其最高位1代表負,其真正數值是-3而不是形式值131(10000011轉換成十進制等于131)。所以,為區(qū)別起見,將帶符號位的機器數對應的真正數值稱為機器數真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1原碼:原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值.
比如:如果是8位二進制:[+1]原 = 0000 0001,[-1]原 = 1000 0001
第一位是符號位. 因為第一位是符號位, 所以8位二進制數的取值范圍就是:[1111 1111 , 0111 1111],即:[-127 , 127]
原碼是人腦最容易理解和計算的表示方式.反碼:反碼的表示方法是:正數的反碼跟原碼一樣,負數的反碼是在其原碼的基礎上,符號位不變,其余各位取反
比如:[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可見如果一個反碼表示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算補碼:補碼的表示方法是:正數的補碼就是其本身;負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1. (即在反碼的基礎上+1)
比如:[+1] = [00000001]原 = [00000001]反 = [00000001]補
[-1] = [10000001]原 = [11111110]反 = [11111111]補
對于負數, 補碼表示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值
如果有運算得話,負數都是用補碼參與運算的,得到的結果也是補碼,需要減1取反獲得原碼
1.3.2.2 為何要使用原碼, 反碼和補碼
在開始深入學習前, 先死記硬背上面的原碼, 反碼和補碼的表示方式以及計算方法.
現在我們知道了計算機可以有三種編碼方式表示一個數. 對于正數因為三種編碼方式的結果都相同:
[+1] = [00000001]原 = [00000001]反 = [00000001]補
所以不需要過多解釋. 但是對于負數:
[-1] = [10000001]原 = [11111110]反 = [11111111]補
可見原碼, 反碼和補碼是完全不同的. 既然原碼才是被人腦直接識別并用于計算表示方式, 為何還會有反碼和補碼呢?
首先, 因為人腦可以知道第一位是符號位, 在計算的時候我們會根據符號位, 選擇對真值區(qū)域的加減. 但是對于計算機, 加減乘數已經是最基礎的運算, 要設計的盡量簡單. 計算機辨別符號位顯然會讓計算機的基礎電路設計變得十分復雜! 于是人們想出了將符號位參與運算的方法. 我們知道, 根據運算法則減去一個正數等于加上一個負數, 即: 1-1 = 1 + (-1) = 0, 所以機器可以只有加法而沒有減法, 這樣計算機運算的設計就更簡單了.
于是人們開始探索 將符號位參與運算, 并且只保留加法的方法. 首先來看原碼。計算十進制的表達式:
1-1=0
1 - 1 = 1 + (-1)
= [00000001]原 + [10000001]原
= [10000010]原 = -2
如果用原碼表示, 讓符號位也參與計算, 顯然對于減法來說, 結果是不正確的.這也就是為何計算機內部不使用原碼表示一個數.
為了解決原碼做減法的問題, 出現了反碼。計算十進制的表達式:
1-1=0
1 - 1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]反 + [1111 1110]反
= [1111 1111]反 = [1000 0000]原
= -0
發(fā)現用反碼計算減法, 結果的真值部分是正確的. 而唯一的問題其實就出現在0這個特殊的數值上. 雖然人們理解上+0和-0是一樣的, 但是0帶符號是沒有任何意義的. 而且會有[0000 0000]原和[1000 0000]原兩個編碼表示0.
于是補碼的出現, 解決了0的符號以及兩個編碼的問題:
1-1 = 1 + (-1)
= [0000 0001]原 + [1000 0001]原
= [0000 0001]補 + [1111 1111]補
= [0000 0000]補=[0000 0000]原
這樣0用[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128:
(-1) + (-127) = [1000 0001]原 + [1111 1111]原
= [1111 1111]補 + [1000 0001]補
= [1000 0000]補
-1-127的結果應該是-128, 在用補碼運算的結果中, [1000 0000]補 就是-128. 但是注意因為實際上是使用以前的-0的補碼來表示-128, 所以-128沒有原碼和反碼表示.(對-128的補碼表示[1000 0000]補算出來的原碼是[0000 0000]原, 這是不正確的)
使用補碼, 不僅僅修復了0的符號以及存在兩個編碼的問題, 而且還能夠多表示一個最低數. 這就是為什么8位二進制, 使用原碼或反碼表示的范圍為[-127, +127], 而使用補碼表示的范圍為[-128, 127].
因為機器使用補碼, 所以對于編程中常用到的32位int類型, 可以表示范圍是: [,
] 因為第一位表示的是符號位.而使用補碼表示時又可以多保存一個最小值.
1.3.2.3 負數運算
負數參與的運算,得到的是 補碼,需要將補碼先減1,然后逐位取反,得到原碼,即為運算結果。
0例外,如果得到的是0,則不需減1和取反。
另外,兩個正數運算后得到的就是原碼,不需減1和取反。
舉例:
1^-1,
-1 :
10000000000000000000000000000001--原碼
11111111111111111111111111111110--反碼
11111111111111111111111111111111--補碼
1
00000000000000000000000000000001`--原碼
則1^-1等于
11111111111111111111111111111111^
00000000000000000000000000000001=
11111111111111111111111111111110--補碼
11111111111111111111111111111101--反碼
10000000000000000000000000000010--原碼==-2
即1^-1=-2
舉例:
1^-2
-2
10000000000000000000000000000010--原碼
01111111111111111111111111111101--反碼
01111111111111111111111111111110--補碼
1
00000000000000000000000000000001--原碼
則1^-2等于
01111111111111111111111111111110^
00000000000000000000000000000001=
01111111111111111111111111111111--補碼
01111111111111111111111111111110--反碼
10000000000000000000000000000001--原碼==-1
1.3.2.4 轉換16進制為什么需要 &0xff
例如:把漢字轉為16進制需要如下:
@Test
public void testEnHex() throws UnsupportedEncodingException {
String s = "嚴";
byte[] bytes = s.getBytes("utf-8");
StringBuffer sb = new StringBuffer();
for (int i = 0;i<bytes.length;i++){
String s1 = Integer.toHexString(bytes[i] & 0x0ff).toUpperCase();
if(s1.length()<2){
sb.append(0);
}
sb.append(s1);
}
System.out.println(sb.toString());
}
如上的為什么需要 &0x0ff呢
先看下添加和去掉結果:
有&0x0ff是E4B8A5,沒有時是FFFFFFE4FFFFFFB8FFFFFFA5
沒有&0x0ff轉換后多了一串FF
這是因為Integer.toHexString()的接收參數是int,不是byte,于是運算是會先把byte強制轉換為int
由于java中強制轉換是保持值不變,而在計算機中數都是用 補碼 表示的,java中int是32位4個byte, 正數補碼是正數本身,這樣不會有問題,強轉為32位時前面24位會填充0,
而負數的補碼是將其對應正數二進制表示所有位取反(原碼符號位除外,0變1,1變0)后加1,于是32位的0x00 00 00 80(0000 ... 0000 1000 0000)補碼是0xFF FF FF 80(1111 ... 1111 1000 0000),前面是填充的1
所以Integer.toHexString()后就會變成前面多了一串F
所以要得到正確的結果,需要用 Integer.toHexString(card[i] & 0xff),這樣會只取最后8位(1byte=8位二進制),前面都置0,這樣轉換出來就是正確的了
為什么非要添加&0x0ff,不加也有結果,只是長點而已嘛
如果不加&0x0ff,那么保存的字符長度難以統(tǒng)一 ,字符串長度太長。
并且byte的取值范圍在[-128,127]之間,16進制表示用兩個符號就夠了0x00—0xff。負數如果用這么多字符,造成正負數符號長度不統(tǒng)一怎么保存呢?從16進制還原成2進制時怎么按長度區(qū)分各個數字呢?
所以我們把byte與運算&0xff。以-1為例:1111 1111 1111 1111 1111 1111 1111 1111 & 0xff 得到0000 0000 0000 0000 0000 0000 1111 1111即0xff。這個數結果依然是-1。用這種方式處理后,byte不論正負,得到的都是二位的16進制數。以兩位存儲,兩位還原,很方便
還原代碼如下,使用E4B8A5(用&0xff)能得到正確值,但是使用FFFFFFE4FFFFFFB8FFFFFFA5(沒有用&0xff)就不能得到正確的值
public void testHanzi() {
String hexStr = "E4B8A5";
String str = "0123456789ABCDEF" ;
char [] hexs = hexStr.toCharArray();
byte [] bytes = new byte [hexStr.length() / 2 ];
int n;
for ( int i = 0 ; i < bytes.length; i++) {
n = str.indexOf(hexs[ 2 * i]) * 16 ;
n += str.indexOf(hexs[ 2 * i + 1 ]);
bytes[i] = ( byte ) (n & 0xff );
}
System.out.println(new String(bytes));
}
按照16進制兩位兩位判斷,在進行byte強轉時高于127時,溢出轉為負值
1.3.3 常用的位運算符運算
常用的位運算符--0在位運算中是比較特殊的
^ 異或:相同為0,相異為1; 任何數與0異或都等于原值。
& 與: 全1為1, 有0為0;任何數與0異或都等于0。
| 或: 有1為1, 全0為0。任何數與0或都等于原值。
<<左移: 補0。
>> 右移:符號位是0補0,是1補1。
>>>無符號右移:補0。
~ 非:逐位取反
1.3.3.1 左右位移
<<:邏輯左移,右邊補0,符號位和其他位一樣.
正數: x<<1一般相當于2x,但是可能溢出.
溢出范圍: ~ (
-1) 二進制表示 010000...000到01111....1111,移位后最高為變?yōu)?了,變成負數了.
負數:
1111111111111111111111111111111 this is 2^31
1000000000000000000000000000000 this is 2^30
x<<1一般也相當于2x,也有可能溢出.所以, x*32可以寫成x<<5
溢出范圍: ~-(
+1)二進制表示
10000...000到101111...1111,移位后最高為變成0了,變成正數了.
>> :算術右移,和上面的不對應,為正數時左邊補0,為負數時左邊補1.
x>>1,相當于x/2,余數被舍棄,因為這個是縮小,所以不會溢出.
不過有一點要注意: -1右移多少位都是-1.
另外舍棄的余數是正的, 3>>1=1 舍棄的余數是1.
-3>>1=-2 舍棄的余數也是1,而不是-1.
對于正數 x>>1和x/2相等
對于負數x>>1和x/2不一定相等.
>>> :邏輯右移,這個才是和<<對應的
這個把符號位一起移動,左邊補0
對于正數,>>>和>>是一樣的
對于負數,右移之后就變成正數了.
可以使用Integer.toBinaryString(int i)來看01比特,更加直觀.
考慮下面的代碼:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
用移位操作替代乘法操作可以極大地提高性能。下面是修改后的代碼:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
修改后的代碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相于乘以2。相應地,右移1位操作相當于除以2。值得一提的是,雖然移位操作速度快,但可能使代碼比較難于理解,所以最好加上一些注釋。
無符號右移位操作符>>>在將bit串右移位時,從bit串的最左邊填充0,這和帶符號右移位操作符>>不同。>>在將bit串右移位時,從bit串的最左邊填充原來最左邊的位。也就是說,bit串原來最左邊的位是符號位,如果為1,則在帶符號右移時最左邊始終填充1;如果為0,則在帶符號右移時最左邊始終填充0。
移位操作符的例子見下表。
| 操作 | 結果 | 說明 |
|---|---|---|
| 00110010<< 2 | 11001000 | 右邊始終填充0 |
| 00110010 >> 2 | 00001100 | 結果和>>>一樣 |
| 00110010 >>> 2 | 00001100 | 結果和>>一樣 |
| 10110010 >> 2 | 11101100 | 結果和>>>不一樣 |
| 10110010 >>> 2 | 100101100 | 結果和>>不一樣 |
按位與操作符&對兩個bit串按位進行邏輯與,按位或操作符|對兩個bit串按位進行邏輯或,按位異或操作符^對兩個bit串按位進行異或操作。運算規(guī)則如下表所示。
| 按位與 | 按位或 | 按位異或 |
|---|---|---|
| 0 & 0 = 0 | 0 | 0 = 0 | 0 ^ 0 = 0 |
| 0 & 1 = 0 | 0 | 1 = 1 | 0 ^ 1 = 1 |
| 1 & 0 = 0 | 1 | 0 = 1 | 1 ^ 0 = 1 |
| 1 & 1 = 1 | 1 | 1 = 1 | 1 ^ 1 = 0 |
2 基本數據類型
基本類型,或者叫做內置類型,是JAVA中不同于類的特殊類型。它們是我們編程中使用最頻繁的類型
基本類型共有八種,它們分別都有相對應的包裝類。關于它們的詳細信息請如下:
基本類型可以分為三類,字符類型char,布爾類型boolean以及數值類型byte、short、int、long、float、double。
數值類型又可以分為整數類型byte、short、int、long和浮點數類型float、double。JAVA中的數值類型不存在無符號的,它們的取值范圍是固定的,不會隨著機器硬件環(huán)境或者操作系統(tǒng)的改變而改變。實際上,JAVA中還存在另外一種基本類型void,它也有對應的包裝類java.lang.Void,不過我們無法直接對它們進行操作。對于數值類型的基本類型的取值范圍,我們無需強制去記憶,因為它們的值都已經以常量的形式定義在對應的包裝類中了。請看下面的例子:
public class PrimitiveTypeTest {
public static void main(String[] args) {
// byte
System.out.println("基本類型:byte 二進制位數:" + Byte.SIZE);
System.out.println("包裝類:java.lang.Byte");
System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);
System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);
System.out.println();
// short
System.out.println("基本類型:short 二進制位數:" + Short.SIZE);
System.out.println("包裝類:java.lang.Short");
System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);
System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);
System.out.println();
// int
System.out.println("基本類型:int 二進制位數:" + Integer.SIZE);
System.out.println("包裝類:java.lang.Integer");
System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);
System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);
System.out.println();
// long
System.out.println("基本類型:long 二進制位數:" + Long.SIZE);
System.out.println("包裝類:java.lang.Long");
System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);
System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);
System.out.println();
// float
System.out.println("基本類型:float 二進制位數:" + Float.SIZE);
System.out.println("包裝類:java.lang.Float");
System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);
System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);
System.out.println();
// double
System.out.println("基本類型:double 二進制位數:" + Double.SIZE);
System.out.println("包裝類:java.lang.Double");
System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);
System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);
System.out.println();
// char
System.out.println("基本類型:char 二進制位數:" + Character.SIZE);
System.out.println("包裝類:java.lang.Character");
// 以數值形式而不是字符形式將Character.MIN_VALUE輸出到控制臺
System.out.println("最小值:Character.MIN_VALUE="
+ (int) Character.MIN_VALUE);
// 以數值形式而不是字符形式將Character.MAX_VALUE輸出到控制臺
System.out.println("最大值:Character.MAX_VALUE="
+ (int) Character.MAX_VALUE);
}
}
運行結果:
基本類型:byte 二進制位數:8
包裝類:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127
基本類型:short 二進制位數:16
包裝類:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767
基本類型:int 二進制位數:32
包裝類:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647
基本類型:long 二進制位數:64
包裝類:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807
基本類型:float 二進制位數:32
包裝類:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38
基本類型:double 二進制位數:64
包裝類:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308
基本類型:char 二進制位數:16
包裝類:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535
Float和Double的最小值和最大值都是以科學記數法的形式輸出的,結尾的E+數字表示E之前的數字要乘以10的多少倍。比如3.14E3就是3.14×1000=3140,3.14E-3就是3.14/1000=0.00314
大家將運行結果與上表信息仔細比較就會發(fā)現float、double兩種類型的最小值與Float.MIN_VALUE、 Double.MIN_VALUE的值并不相同,這是為什么呢?實際上Float.MIN_VALUE和Double.MIN_VALUE分別指的是float和double類型所能表示的最小正數。也就是說存在這樣一種情況,0到±Float.MIN_VALUE之間的值float類型無法表示,0 到±Double.MIN_VALUE之間的值double類型無法表示。這并沒有什么好奇怪的,因為這些范圍內的數值超出了它們的精度范圍。
需要注意:基本類型存儲在棧中,因此它們的存取速度要快于存儲在堆中的對應包裝類的實例對象。從Java5.0(1.5)開始,JAVA虛擬機(Java Virtual Machine)可以完成基本類型和它們對應包裝類之間的自動轉換。因此我們在賦值、參數傳遞以及數學運算的時候像使用基本類型一樣使用它們的包裝類,但這并不意味著你可以通過基本類型調用它們的包裝類才具有的方法。另外,所有基本類型(包括void)的包裝類都使用了final修飾,因此我們無法繼承它們擴展新的類,也無法重寫它們的任何方法。
附:Java中二進制,八進制,十六進制,十進制間進行相互轉