給大家分享我收藏的幾個不錯的 github 項目榆苞,內(nèi)容都還是不錯的,如果覺得有幫助霞捡,可以順便給個 star语稠。
- 計算機專業(yè)學生必須要啃的書籍推薦: https://github.com/hello-go-maker/cs-books
- Java 實戰(zhàn)項目推薦: https://github.com/hello-go-maker/Java-project
- 推薦一些很不錯的計算機學習教程,包括:數(shù)據(jù)結(jié)構(gòu)弄砍、算法、計算機網(wǎng)絡(luò)输涕、操作系統(tǒng)音婶、Java(spring、springmvc莱坎、springboot衣式、springcloud),也包括多個企業(yè)級實戰(zhàn)項目: https://github.com/hello-go-maker/cs-learn-source
- 【Java面試+Java后端技術(shù)學習指南】:一份通向理想互聯(lián)網(wǎng)公司的面試指南檐什,包括 Java碴卧,技術(shù)面試必備基礎(chǔ)知識、Leetcode乃正、計算機操作系統(tǒng)住册、計算機網(wǎng)絡(luò)、系統(tǒng)設(shè)計瓮具、分布式荧飞、數(shù)據(jù)庫(MySQL、Redis)名党、Java 項目實戰(zhàn)等: https://github.com/hello-java-maker/JavaInterview
一叹阔、基本類型的簡介
基本類型的兩條準則:
- Java中,如果對整數(shù)不指定類型传睹,默認時int類型耳幢,對小數(shù)不指定類型,默認是double類型欧啤。
- 基本類型由小到大睛藻,可以自動轉(zhuǎn)換,但是由大到小邢隧,則需要強制類型轉(zhuǎn)換修档。
所占的字節(jié)數(shù):
byte: 1個字節(jié);
char: 2個字節(jié)府框;
short: 2個字節(jié)吱窝;
int: 4個字節(jié)讥邻;
long: 8個字節(jié);
float: 4個字節(jié)院峡;(6位小數(shù)兴使,指數(shù)是:10-38~1038; 范圍:)
double: 8個字節(jié);
char:Java中用 "\u四位十六進制的數(shù)字 (即使在注釋中出現(xiàn)\u照激,后面如果
跟的不是4個16進制的數(shù)字发魄,也會報錯)"表示將字符轉(zhuǎn)換成對應(yīng)的unicode編 碼;也可以用字符來賦值如: char c="\u0000" 俩垃,char的默認初始化值励幼,unicode的null字符
基本類型的后綴:
long : l 或 L
float: f 或 F;
double: d 或 D
二口柳、類型轉(zhuǎn)換
正如前面所說的苹粟,類型由大到小,是必需強制轉(zhuǎn)換跃闹。但這并不意味著需要用戶手動強制轉(zhuǎn)換 —— 也就是 隱式轉(zhuǎn)換嵌削。隱式轉(zhuǎn)換 說的透徹點就是由編譯器來進行強制轉(zhuǎn)換,不需要用戶再去寫強制轉(zhuǎn)換的代碼望艺。下面的前兩個小點所說的便是特殊的隱式類型轉(zhuǎn)換苛秕。
本小節(jié)所討論的類型轉(zhuǎn)換是不包括 類型由小到大的轉(zhuǎn)換,討論的是其他比較容易讓人迷惑的類型轉(zhuǎn)換
1. int類型的字面常量轉(zhuǎn)換成比int類型低的變量類型
所謂的字面常量就是值的本身找默,如 5艇劫、7、“aa”等等惩激。我們先看個例子:
public static void main(String[] args) {
int a = 8; //8是字面常量
byte b = 9; //9是字面常量
char c = 9+5;//常量表達式
short s = (short) (c+10); //變量表達式港准,需要顯式強制轉(zhuǎn)換
}
上面的代碼是經(jīng)過編譯的,是正確的咧欣。b是byte類型浅缸,但b=9不需要顯式地手動強制轉(zhuǎn)換,這是因為9是字面常量魄咕,是由JVM自動完成衩椒。
??我們再來看一下c=9+5
,c是char類型哮兰,9+5得到結(jié)果是int類型毛萌,但也不需要顯式地手動強制轉(zhuǎn)換。這是因為 9+5是常量表達式喝滞,所以在編譯期間已經(jīng)由編譯器計算出結(jié)果了阁将,即經(jīng)過編譯后,相當于 c=14右遭,也是字面常量做盅,所以可以隱式轉(zhuǎn)換缤削。同理,short s = (short) (c+10);
子所以不能隱式轉(zhuǎn)換吹榴,就是因為表達式不是常量表達式亭敢,包含了變量,只能在運行期間完成图筹,所以就要手動強制轉(zhuǎn)換帅刀。
整形字面常量隱式轉(zhuǎn)換的限制:
- 整形字面常量的大小超出目標類型所能表示的范圍時,要手動強制類型轉(zhuǎn)換远剩。
byte b = 128;//編譯錯誤扣溺,128超出byte類型所能表示的范圍
byte c = (byte)128;//編譯通過
- 對于傳參數(shù)時,必須要顯式地進行強制類型轉(zhuǎn)換瓜晤,明確轉(zhuǎn)換的類型
編譯器子所以這樣要求锥余,其實為了避免 方法重載出現(xiàn)的隱式轉(zhuǎn)換 與 小類型自動轉(zhuǎn)大類型 發(fā)生沖突。
public static void main(String[] args) {
shortMethod(8);//編譯錯誤
shortMethod((short)8); //編譯通過
longMethod(8);//編譯通過活鹰,因為這是小類型變成大類型,是不需要強制類型轉(zhuǎn)換的
}
public static void shortMethod(short c){
System.out.println(c);
}
public static void longMethod(short l){
System.out.println(l);
}
- char類型的特殊情況 :下面再細講
2. 復(fù)合運算符的隱式轉(zhuǎn)換
復(fù)合運算符(+=只估、-=志群、=、/=蛔钙、%=)是可以將右邊表達式的類型自動強制轉(zhuǎn)換成左邊的類型*
public static void main(String[] args) {
int a = 8;
short s = 5;
s += a;
s += a+5;
}
s+=a锌云、s+=a+5
;的表達式計算結(jié)果都是int類型,但都不需要手動強制轉(zhuǎn)換吁脱。其實桑涎,如果是反編譯這段代碼的class文件,你會發(fā)現(xiàn)s+=a;兼贡,其實是被編譯器處理成了
s=(short)(s+a)
也就是說對于所有的復(fù)合運算的隱式類型轉(zhuǎn)換攻冷,其實是編譯器自動添加類型轉(zhuǎn)換的代碼。
所以遍希,相對于整形字面常量的隱式轉(zhuǎn)換等曼,復(fù)合運算符的隱式轉(zhuǎn)換則沒有任何限制因為前者只能在編譯器期間發(fā)生,后者則是編譯器實實在在的補全了類型轉(zhuǎn)換的代碼凿蒜。
3. 特殊的char類型
char類型在基本類中是一個比較特殊的存在禁谦。這種特殊性在于char類型是一個無符號類型,所以char類型與其他基本類型不是子集與父集間的關(guān)系(其他類型都是有符號的類型)废封。也就是說州泊,char類型與byte、short之間的轉(zhuǎn)換都需要顯式的強制類型轉(zhuǎn)換(小類型自動轉(zhuǎn)換成大類型失斊蟆)遥皂。
同時力喷,由于char類型是一個無符號類型,所以對于整形字面常量的隱式轉(zhuǎn)換的限制渴肉,不僅包括字面常量數(shù)值的大小不能超出2個字節(jié)冗懦,還包括字面常量數(shù)值不能為負數(shù)
byte b = 2;
char c = 2;//編譯通過
c = 100000000000;//編譯不通過,超出char類型的范圍
char d = -2//字面常量為負數(shù)仇祭,編譯不通過
d = (char)-100;//編譯通過
char f = (char)b; //編譯通過披蕉,必須顯式的強制類型轉(zhuǎn)換
f = b;//編譯不通過,不能隱式轉(zhuǎn)換
int i = c;//編譯通過乌奇,可以不需要強制類型轉(zhuǎn)換
short s = (short) c;//編譯通過没讲,必須顯式地強制類型轉(zhuǎn)換
char類型是無符號的類型,這種無符號也體現(xiàn)在在其轉(zhuǎn)換成int類型時礁苗,也就是說爬凑,char類型在擴展時,也是按無符號的方式擴展试伙,擴展位填0嘁信。我們來看一個例子:
public static void main(String[] args) {
short s = -5;
char c = (char)s;
System.out.println(c==s); //false
System.out.println("(int)c = "+(int)c); //轉(zhuǎn)換成int類型,值為65531
System.out.println("(short)c = "+(short)c); //-5
System.out.println("(int)s = "+(int)s);//-5
}
運行結(jié)果:
false
(int)c?=?65531
(short)c?=?-5
(int)s?=?-5
從上面的結(jié)果發(fā)現(xiàn)疏叨,char類型的c 與 short類s其實存儲字節(jié)碼內(nèi)容是一樣的潘靖,但由于前者是無符號,所以擴展成int類型的結(jié)果是 65531蚤蔓,而不是 -5卦溢。運算符==比較的就是他們擴展成int類型的值,所以為fasle秀又。
對char類型的類型轉(zhuǎn)換单寂,可以總結(jié)成以下幾點:
- char類型與byte、short的相互轉(zhuǎn)換吐辙,都需要顯式地強類型制轉(zhuǎn)換宣决。
- 對于數(shù)值是負數(shù)的,都需要進行顯式地強制類型轉(zhuǎn)換昏苏,特別是在整形字面常量的隱式轉(zhuǎn)換中疲扎。
- char類型轉(zhuǎn)換成int、long類型是符合 小類型轉(zhuǎn)大類型的規(guī)則捷雕,即無需要強制類型轉(zhuǎn)換椒丧。
4. 運算結(jié)果的類型
在Java中,一個運算結(jié)果的類型是與表達式中類型最高的相等救巷,如:
char cc = 5;
float dd = 0.6f+cc;//最高類型是float壶熏,運算結(jié)果是float
float ee = (float) (0.6d+cc);//最高類型是double,運算結(jié)果也是double
int aa = 5+cc;//最高類型是int浦译,運算結(jié)果也為int
但是棒假,對于最高類型是byte溯职、short、char的運算來說帽哑,則運行結(jié)果卻不是最高類型谜酒,而是int類型∑拚恚看下面的例子僻族,c、d運算的最高類型都是char屡谐,但運算結(jié)果卻是int述么,所以需要強制類型轉(zhuǎn)換。
byte b = 2;
char a = 5;
char c = (char) (a+b);//byte+char愕掏,運算結(jié)果的類型為int度秘,需要強制類型轉(zhuǎn)換
int e = a+b;//編譯通過,不需要強制類型轉(zhuǎn)換饵撑,可以證明是int
char d = (char) (a+c);//char+char剑梳,
short s1 = 5;
short s2 = 6;
short s3 =(short)s1+s2;
綜上所述,java的運算結(jié)果的類型有兩個性質(zhì):
- 運算結(jié)果的類型必須是int類型或int類型以上滑潘。
- 最高類型低于int類型的垢乙,運算結(jié)果都為int類型。否則众羡,運算結(jié)果與表達式中最高類型一致侨赡。
三蓖租、浮點數(shù)類型
1. 浮點類型的介紹
我們都知道粱侣,long類型轉(zhuǎn)換成float類型是不需要強制類型轉(zhuǎn)換的,也就是說相對于flaot類型蓖宦,long類型是小類型齐婴,存儲的范圍要更小。然而flaot只占了4個字節(jié)稠茂,而long卻占了8個字節(jié)柠偶,long類型的存儲空間要比float類型大。這究竟是怎么一回事睬关,我們接下來將細細分析诱担。
浮點數(shù)使用 IEEE(電氣和電子工程師協(xié)會)格式。 浮點數(shù)類型使用 符號位电爹、指數(shù)蔫仙、有效位數(shù)(尾數(shù))來表示。要注意一下丐箩,尾數(shù)的最高
在java中摇邦,float 和 double 的結(jié)構(gòu)如下:
|類 型|符 號 位|指 數(shù) 域|有效位域|
|-|-|-|
|float|1位|8位|23位|
|double|1位 |11位|52位|
符號位: 0為正恤煞,1為負;
指數(shù)域: 無符號的施籍,float的偏移量為127(即float的指數(shù)范圍是-126~127居扒,),double
有效位域: 無符號的丑慎;
2. 浮點類型的兩個需要注意的地方
1)存儲的小數(shù)的數(shù)值可能是模糊值
public static void main(String[] args) {
double d1 = 0.1;
double d2 = 0.2;
System.out.println(d1+d2 == 0.3);
System.out.println(d1+d2);
}
運行結(jié)果:
false
0.30000000000000004
上述的運算結(jié)果并不是錯誤喜喂。這是因為無法用二進制來準確地存儲的0.3,這是一個無限循環(huán)的值立哑,與10進制的1/3很相似夜惭。不只是0.3,很多小數(shù)都是無法準確地用浮點型表示铛绰,其實這是由 小數(shù)的十進制轉(zhuǎn)成二進制的算法所決定的诈茧,十進制的小數(shù)要不斷乘2,知道最后的結(jié)果為整數(shù)才是最后的二進制值捂掰,但這有可能怎么也得不到整數(shù)敢会,所以最后得到的結(jié)果可能是一個 無限值 ,浮點型就無法表示了
但是對于 整數(shù) 來說这嚣,在浮點數(shù)的有效范圍內(nèi)鸥昏,則都是精確的。同樣姐帚,也是由于轉(zhuǎn)換算法:十進制的整數(shù)轉(zhuǎn)成二進制的算法是不斷對2求余數(shù)吏垮,所以 不會存在無限值的情況;
2)浮點數(shù)的有效位及精度
浮點型所能表示的有效位是有限的罐旗,所以哪怕是整數(shù)膳汪,只要超出有效位數(shù),也只能存儲相似值九秀,也就是該數(shù)值的最低有效位將會丟失,從而造精度丟失遗嗽。
??float類型的二進制有效位是24位,對應(yīng)十進制的7 ~ 8位數(shù)字鼓蜒;double類型的二進制53位痹换,對應(yīng)十進制的10 ~ 11位數(shù)字。
double都弹、float類型 所能表示的范圍比int娇豫、long類型表示的范圍要廣,也浮點類型屬于大類型畅厢。但是冯痢,并不能完美地表整形,浮點類型的精度丟失會造成一些問題。
public static void main(String[] args) {
int a = 3000000;
int b = 30000000;
float f1 = a;
float f2 = b;
System.out.println("3000000==3000001 "+(f1==f1+1));
System.out.println("30000000==30000001 "+(f2==f2+1));
System.out.println("3000000的有效二進制位數(shù):"+ Integer.toBinaryString(a).length());
System.out.println("30000000的有效二進制位數(shù):"+ Integer.toBinaryString(b).length());
}
運行結(jié)果:
3000000 == 3000001 ?false
30000000 == 30000001 ?true
3000000的有效二進制位數(shù):?22
30000000的有效二進制位數(shù):?25
上面的例子很好體現(xiàn)了精度丟失所帶來的后果:30000000==30000001
的比較居然為true了系羞。而造成這種結(jié)果的原因就是 30000000的有效二進制位數(shù)是25位郭计,超出了float所能表示的有效位24位,最后一位就被舍去椒振,所以就造成在剛加的1也被舍去昭伸,因此30000000的加一操作前后的浮點型表示是一樣的。
當然澎迎,并不是超出浮點型的有效位就不能精確表示庐杨,其實,主要看的是最高有效位與最低非0有效位之間的 “間隙”夹供,如果間隙的在浮點型的有效位數(shù)內(nèi)灵份,自然可以精確表示,因為舍去的低有效位都是0哮洽,自然就無所謂了填渠。如果上面的例子的浮點型用的是double就不會丟失精度了,因為double的精度是52位鸟辅。
3)解決浮點型精度丟失的問題
浮點型帶來精度丟失的問題是很讓人頭痛的氛什,所以一般情況下,在程序中是不會使用float匪凉、double來存儲比較大的數(shù)據(jù)枪眉。而商業(yè)計算往往要求結(jié)果精確≡俨悖《Effactive Java》書中有一句話:
float和double類型的主要設(shè)計目標是為了科學計算和工程計算
JDK為此提供了兩個高精度的大數(shù)操作類給我們:BigInteger贸铜、BigDecimal。
作者:jinggod
出處:http://www.cnblogs.com/jinggod/p/8424583.html
最后聂受,給大家分享我收藏的幾個不錯的 github 項目蒿秦,內(nèi)容都還是不錯的,如果覺得有幫助饺饭,可以順便給個 star渤早。
- 計算機專業(yè)學生必須要啃的書籍推薦: https://github.com/hello-go-maker/cs-books
- Java 實戰(zhàn)項目推薦: https://github.com/hello-go-maker/Java-project
- 推薦一些很不錯的計算機學習教程职车,包括:數(shù)據(jù)結(jié)構(gòu)瘫俊、算法、計算機網(wǎng)絡(luò)悴灵、操作系統(tǒng)扛芽、Java(spring、springmvc积瞒、springboot川尖、springcloud),也包括多個企業(yè)級實戰(zhàn)項目: https://github.com/hello-go-maker/cs-learn-source
- Java面試+Java后端技術(shù)學習指南】:一份通向理想互聯(lián)網(wǎng)公司的面試指南茫孔,包括 Java叮喳,技術(shù)面試必備基礎(chǔ)知識被芳、Leetcode、計算機操作系統(tǒng)馍悟、計算機網(wǎng)絡(luò)畔濒、系統(tǒng)設(shè)計、分布式锣咒、數(shù)據(jù)庫(MySQL侵状、Redis)、Java 項目實戰(zhàn)等: https://github.com/hello-java-maker/JavaInterview