《Java編程思想第四版》筆記---1~9章(1)面向?qū)ο蠡A
1.java中的4種訪問制權(quán)限
(1)public:最大訪問控制權(quán)限,對所有的類都可見咒循。
(2)protect:同一包可見杀餐,不在同一個包的所有子類也可見干发。
(3)default:包訪問權(quán)限,即同一個包中的類可以可見史翘。默認不顯示指定訪問控 制權(quán)限時就是default包訪問控制權(quán)限枉长。
(4)private:最嚴格的訪問控制權(quán)限,僅該類本身可見琼讽,對外一切類都不可以訪問(反射機制可以訪問)必峰。
2.面向?qū)ο缶幊讨袃煞N對象組合方式(is-a 和 has-a)
(1).is-a組合:一個類繼承具有相似功能的另一個類,根據(jù)需要在所繼承的類基礎上進行擴展钻蹬。
優(yōu)點:具有共同屬性和方法的類可以將共享信息抽象到父類中吼蚁,增強代碼復用性,同時也是多態(tài)的基礎问欠。
缺點:子類中擴展的部分對父類不可見肝匆,另外如果共性比較少的時候使用繼承會增加冗余代碼。
(2).has-a組合:has-a組合是在一個類中引用另一個類作為其成員變量顺献。
優(yōu)點:可擴展性和靈活性高旗国。在對象組合關系中應優(yōu)先考慮has-a組合關系。
缺點:具有共性的類之間看不到派生關系注整。
3.多態(tài):
在面向?qū)ο缶幊讨心茉宇愔袚碛泻透割愊嗤椒ê灻姆椒ǚQ為子類方法覆蓋父類方法,當調(diào)用子類方法的某個操作時肿轨,不必明確知道子類的具體類型借浊,只需要將子類類型看作是父類的引用調(diào)用其操作方法,在運行時萝招,JVM會根據(jù)引用對象的具體子類類型而調(diào)用應該的方法,這就是多態(tài)存捺。
多態(tài)的基礎是java面向?qū)ο缶幊痰耐斫壎C制槐沼。編程中有如下兩種綁定機制:
(1)早綁定(前期綁定):一般在非面向?qū)ο缶幊陶Z言中使用曙蒸,在程序編譯時即計算出具體調(diào)用方法體的內(nèi)存地址。
(2)晚綁定(后期綁定):面向?qū)ο缶幊陶Z言中經(jīng)常使用岗钩,在程序編譯時無法計算出具體調(diào)用方法體的內(nèi)存地址纽窟,只進行方法參數(shù)類型和返回值類型的校驗,在運行時才能確定具體要調(diào)用方法體的內(nèi)存地址兼吓。
4.java單繼承的優(yōu)點:
相比于C++的多繼承臂港,java只支持類的單繼承,java中的所有類的共同基類是 Object類视搏,Object類是java類樹的唯一根節(jié)點审孽,這種單繼承有以下好處:
(1).單繼承可以確保所有的對象擁有某種共同的特性森篷,這樣JVM虛擬機對所有的類進行系統(tǒng)級的操作將提供方便绰更,所有的java對象可以方便地在內(nèi)存堆棧中創(chuàng)建禁悠,傳遞參數(shù)也變的更加方便簡單域携。
(2).java的單繼承使得實現(xiàn)垃圾回收器功能更加容易功戚,因為可以確保JVM知道所有對象的類型信息拱烁。
5.選擇容器對象的兩個原則:
(1).容器所能提供不同的類型的接口和外部行為是否能夠滿足需求桨武。
(2).不同容器針對不同的操作效率不同于个。
例如:ArrayList中漓滔,隨機訪問元素是一個耗時固定的操作编饺,而LinkedList,隨機訪問元素需要在列表中走動响驴,訪問的元素越靠尾透且,花費的時間越長。
ArrayList和LinkedList的大致區(qū)別如下:
1.ArrayList是實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)踏施,LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)石蔗。
2.對于隨機訪問get和set,ArrayList優(yōu)于LinkedList畅形,因為LinkedList要移動指針养距。
3.對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢日熬,因為ArrayList要移動數(shù)據(jù)棍厌。
6.類型轉(zhuǎn)換:
Java中有兩種常見的類型轉(zhuǎn)換:向上類型轉(zhuǎn)換(upcast)和向下類型轉(zhuǎn)換(downcast):
(1)向上類型轉(zhuǎn)換(upcast):
向上類型轉(zhuǎn)換是將子類類型對象強制轉(zhuǎn)換為父類類型,經(jīng)典用法是面向?qū)ο蟮亩鄳B(tài)特性竖席。向上類型轉(zhuǎn)換時耘纱,子類對象的特性將不可見,只有子類從父類繼承的特性仍然保持可見毕荐,向上類型轉(zhuǎn)換時編譯器會自動檢查是否類型兼容束析,通常是安全的。
(2)向下類型轉(zhuǎn)換(downcast):
向下類型轉(zhuǎn)換是將父類類型強制轉(zhuǎn)換為子類類型憎亚,轉(zhuǎn)換過后父類中不可見的子類特性又恢復可見性员寇,向下類型轉(zhuǎn)換時弄慰,編譯器無法自動檢測是否類型兼容,往往會產(chǎn)生類型轉(zhuǎn)換錯誤的運行時異常蝶锋,通常不安全陆爽。
7.java中5個存放數(shù)據(jù)的地方:
(1)寄存器(Registers):位于CPU內(nèi)部,是速度最快的存儲區(qū)扳缕,但是數(shù)量和容量有限慌闭。在java中不能直接操作寄存器。
( 2)棧(Stack):棧位于通用隨機訪問存儲器 (General random-access memory躯舔,RAM驴剔,內(nèi)存) 中,通過處理器的棧指針訪問庸毫,棧指針從棧頂向棧底分配內(nèi)存仔拟,從棧底向棧頂釋放內(nèi)存。棧是僅次于寄存器的速度第二快的存儲器飒赃,在java程序中利花,一般的8種基本類型數(shù)據(jù)和對象的引用通常存放在棧內(nèi)存中,不通過new關鍵字的字符串對象也是存放在棧的字符串池中载佳。
優(yōu)勢是炒事,存取速度比堆要快,僅次于寄存器蔫慧,棧數(shù)據(jù)可以共享挠乳。
缺點是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的姑躲,缺乏靈活性睡扬。
(3)堆(Heap):也是位于通用隨機訪問存儲器 (General random-access memory,RAM黍析,內(nèi)存) 中的共享內(nèi)存池卖怜。Java的堆是一個運行時數(shù)據(jù)區(qū),類的對象從中分配空間阐枣,凡是通過new關鍵字創(chuàng)建的對象都存放在堆內(nèi)存中马靠,它們不需要程序代碼來顯式的釋放。堆是由垃圾回收來負責的蔼两。
優(yōu)勢是可以動態(tài)地分配內(nèi)存大小甩鳄,編譯器對它的生命周期一無所知,因為它是在運行時動態(tài)分配內(nèi)存的额划,Java的垃圾收集器會自動收走這些不再使用的數(shù)據(jù)妙啃。
缺點是,由于要在運行時動態(tài)分配內(nèi)存俊戳,存取速度較慢揖赴。
(4).常量存儲器(Constant storage):java中的常量是存放在系統(tǒng)內(nèi)嵌的只讀存儲器中(read-only memory,ROM)的茁瘦。
(5).非隨機存儲器(Non-RAM storage):對于流對象和持久化對象,通常存放在程序外的存儲器储笑,如硬盤。
8.異常處理
異常提供了一種從錯誤狀況進行可靠恢復的途徑圆恤。不能只單單拋出異常而不處理突倍,可以借助異常情況進行程序的有效恢復,編出更加健壯的程序盆昙。
異常處理不是面向?qū)ο蟮奶卣饔鹄诿嫦驅(qū)ο笳Z言出現(xiàn)之前已經(jīng)存在。
9.并發(fā)編程
需要解決共享資源問題
10.基礎數(shù)據(jù)類型
boolean 1位 - - Boolean
char 16位 Unicode 0 Unicode 2的16次方-1 Character
byte 8位 -128 +127 Byte(注釋①)
short 16位 -2的15次方 +2的15次方-1 Short(注釋①)
int 32位 -2的31次方 +2的31次方-1 Integer
long 64位 -2的63次方 +2的63次方-1 Long
float 32位 IEEE754 IEEE754 Float
double 64位 IEEE754 IEEE754 Double
Void - - - Void(注釋①)
①:到Java 1.1才有淡喜,1.0版沒有秕磷。
數(shù)值類型全都是有符號(正負號)的,所以不必費勁尋找沒有符號的類型炼团。
boolean 類型的存儲空間沒有明確指定澎嚣。
12.對象
(1)對象并不具備基本數(shù)據(jù)類型一樣的生命周期,它可以存活在作用域之外瘟芝。
(2)基本數(shù)據(jù)類型如果沒有初始化也會獲得一個默認值易桃,這只限于作為類的成員變量時才有,并不適用于局部變量锌俱。所以定義變量時最好初始化一個固定值晤郑。
Boolean false
Char '\u0000'(null)
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
13.注釋和嵌入式文檔
注釋三種:
(1)單行注釋: //
(2)多行注釋: /* /
進行編譯時,/和/之間的所有東西都會被忽略
(3)文檔注釋:/* */
javadoc只能為public(公共)和protected(受保護)成員處理注釋文 檔贸宏≡烨蓿“private”(私有)和“友好”(詳見5章)成員的注釋會被忽略,我們看不到任何輸出(也可以用-private標記包括private成員)吭练。
文檔注釋符號:
(1)@see:引用其他類
所有三種類型的注釋文檔都可包含@see標記诫龙,它允許我們引用其他類里的文檔。對于這個標記线脚,javadoc會生成相應的HTML赐稽,將其直接鏈接到其他文檔。格式如下:
@see 類名
@see 完整類名
@see 完整類名#方法名
(2)類文檔標記
@version 版本信息
其中浑侥,“版本信息”代表任何適合作為版本說明的資料姊舵。若在javadoc命令行使用了“-version”標記,就會從生成的HTML文檔里提取出版本信息寓落。
@author 作者信息
其中括丁,“作者信息”包括您的姓名、電子函件地址或者其他任何適宜的資料伶选。若在javadoc命令行使用了“-author”標記史飞,就會專門從生成的HTML文檔里提取出作者信息尖昏。
可為一系列作者使用多個這樣的標記,但它們必須連續(xù)放置构资。全部作者信息會一起存入最終HTML代碼的單獨一個段落里抽诉。
(3)變量文檔標記
變量文檔只能包括嵌入的HTML以及@see引用。
(4)方法文檔標記
@param 參數(shù)名 說明
其中吐绵,“參數(shù)名”是指參數(shù)列表內(nèi)的標識符迹淌,而“說明”代表一些可延續(xù)到后續(xù)行內(nèi)的說明文字。一旦遇到一個新文檔標記己单,就認為前一個說明結(jié)束唉窃。可使用任意數(shù)量的說明纹笼,每個參數(shù)一個纹份。
@return 說明
其中,“說明”是指返回值的含義廷痘。它可延續(xù)到后面的行內(nèi)蔓涧。
@exception 完整類名 說明
其中,“完整類名”明確指定了一個違例類的名字牍疏,它是在其他某個地方定義好的蠢笋。而“說明”(同樣可以延續(xù)到下面的行)告訴我們?yōu)槭裁催@種特殊類型的違例會在方法調(diào)用中出現(xiàn)。
@deprecated
這是Java 1.1的新特性鳞陨。該標記用于指出一些舊功能已由改進過的新功能取代昨寞。該標記的作用是建議用戶不必再使用一種特定的功能,因為未來改版時可能摒棄這一功能厦滤。若將一個方法標記為@deprecated援岩,則使用該方法時會收到編譯器的警告。
14.操作符
(1)賦值=
區(qū)分基本數(shù)據(jù)類型和非基本數(shù)據(jù)類型得賦值掏导,基本數(shù)據(jù)類型是直接內(nèi)容賦值把內(nèi)容復制給新的變量享怀;而非基本數(shù)據(jù)類型是引用賦值(別名現(xiàn)象),指向的是同一塊內(nèi)存區(qū)域趟咆。
Java中賦值運算是把賦值運算符”=”右邊的值簡稱右值拷貝到賦值運算符左邊的變量添瓷,如a=b,即把b代表的變量或常量值復制給變量a,切記a只能是變量,不能說常量值值纱。
a.原始類型賦值運算:
Java中8種原始數(shù)據(jù)類型賦值運算是將賦值運算符右邊的值拷貝到賦值運算符左邊的變量中鳞贷。
原始類型賦值運算后,無論改變賦值運算符那一邊的值虐唠,都不會影響賦值運算符另一邊的值搀愧。
b.引用類型的賦值運算:
Java中除了8中原始數(shù)據(jù)類型外,所有的數(shù)據(jù)類型都是對象類型,對象類型的賦值運算是操作引用咱筛,如a=b搓幌,把b引用賦值給a引用,即原本b引用指向的對象現(xiàn)在由a和b引用同時指向迅箩。
引用賦值運算符又叫別名運算符溉愁,即它相當于給引用對象取了一個別名,其實引用的還是同一個對象饲趋。
引用類型的賦值運算叉钥,如果賦值運算符任意一邊的引用改變了被引用對象的值,賦值運算符另一邊的引用也會受影響篙贸,因為兩個引用指向的是同一個被引用的對象。
(2)算術操作符
加枫疆、減爵川、乘、除息楔、取模
(3)一元加減
x=-a;
減號用于改變數(shù)據(jù)的符號寝贡,加號與減號相對應。
(4)自增自減
后綴:i++ i-- 先生成值再計算
前綴:++i --i 先自增或自減值依,再生成值
例如:
int i=1;
int a=1;
int b=a+ ++i;
輸出:b=3
如果 int b=a+i++;
輸出:b=2,i=2
(5)關系操作符(<,>,<=,>=,==)
==和!=適用于所有的基本數(shù)據(jù)類型圃泡,對于非基本數(shù)據(jù)類型的對象要使用等于和不等于要重寫equal方法。
(6)邏輯操作符(&&愿险,||颇蜡,!)
“與”辆亏,“或”风秤,“非”只適用于布爾值。存在“短路”現(xiàn)象扮叨,對于&&運算缤弦,只要前面的返回false,后面的就不會去計算彻磁;||運算碍沐,對于前面存在結(jié)果為true的運算,后面的運算就不會執(zhí)行衷蜓。
(7)直接常量
long L/l
float F/f
double D/d
十六進制 0X/0x 前綴
八進制 0前綴
指數(shù)計數(shù)法:
e:代表自然對數(shù)基數(shù)累提,約等于2.718(Math.E)
例:1.39E-43
(8)位操作符(&,|)
操作的對象是整數(shù)基本數(shù)據(jù)類型的二進制位恍箭。
(9)移位運算:
左移運算符<<:將比特位左移指定位數(shù)刻恭,右邊部分補0,左移一位相當于乘2。
右移運算符>>:將比特位右移指定位數(shù)鳍贾,如果是正數(shù)鞍匾,左邊第一位(符號位)補0,其余位補0骑科,如果是負數(shù)橡淑,左邊第一位補1,其余位補0咆爽。右移一位相當于除2梁棠。
無符號右移運算符>>>:將比特位右移指定位數(shù),不論是正數(shù)或者負數(shù)斗埂,左邊移除位統(tǒng)統(tǒng)補0符糊。
移位可與賦值結(jié)合使用(<<=,>>=,>>>=),不過要注意數(shù)據(jù)類型轉(zhuǎn)換帶來的問題呛凶,例如byte和short無符號右移男娄,會被轉(zhuǎn)成int類型再右移,然后賦值回原類型(byte或short)產(chǎn)生數(shù)據(jù)截斷漾稀,可能得到-1的錯誤結(jié)果模闲。
(10)三元操作符(X?a:b)
(11)字符操作符+和+=(字符串連接符)
注意:表達式以字符串開頭,后面的操作數(shù)全部會轉(zhuǎn)換成字符串操作崭捍。
例:
int a=0,b=1,c=2;
String d = "a,b,c";
print(d+a+b+c);
輸出:a,b,c012
(12)類型轉(zhuǎn)換
窄化轉(zhuǎn)換:可能面臨數(shù)據(jù)丟失尸折。需要顯式轉(zhuǎn)換。
int i=200;
long c=(long)i;
擴展轉(zhuǎn)換:轉(zhuǎn)換是安全的殷蛇。
注意:java中是不用考慮移植問題的实夹,所以沒有sizeof()用于計算數(shù)據(jù)類型在內(nèi)存的大小。
boolean類型是不能轉(zhuǎn)換類型的粒梦。
15.java中收擦,比int類型小的原始類型(char、byte谍倦、short)進行數(shù)學運算或者位運算時塞赂,數(shù)據(jù)類型首先轉(zhuǎn)換成int類型,然后進行相應的運算昼蛀。
16.swich語句
選擇因子必須是int或char整數(shù)值宴猾,也可以是5新增的enum類型。
17.方法重載(overloading)
方法同名叼旋,參數(shù)列表(順序仇哆,類型,個數(shù))不同稱為方法重載夫植,注意方法的返回值類型不同不能作為方法重載讹剔。
注意:重載的方法參數(shù)類型涉及到轉(zhuǎn)型的情況油讯,類型提升或窄化。char類型找不到合適的方法延欠,可以提升成int類型陌兑。
(1)void m1(int i){}
(2)void m1(long i){}
類型提升:
int k=100;
m1(k);
如果存在(1)(2),調(diào)用的是(1)由捎;
如果只存在(2)兔综,k會由int類型轉(zhuǎn)成long類型;
類型窄化:
long k=100l;
m1(k);
如果存在(1)(2)狞玛,調(diào)用的是(2)软驰;
如果只存在(1),k會由long類型轉(zhuǎn)成int類型,數(shù)據(jù)可能發(fā)生丟失心肪;
18.默認構(gòu)造器
沒有構(gòu)造器情況下锭亏,編譯器會自動創(chuàng)建一個默認的構(gòu)造器(沒有參數(shù)),如果定義了構(gòu)造器硬鞍,編譯器就不會幫你創(chuàng)建默認構(gòu)造器贰镣。
19.this關鍵字
this關鍵字只能在方法中使用,表示調(diào)用該方法的對象的引用膳凝。同一個類中的方法互相調(diào)用不用使用this關鍵字,使用了也沒有錯恭陡。
20.static方法是沒有this的方法蹬音,它是屬于某個類的方法,跟類的對象無關休玩,所以就沒有this著淆,通過類名可以直接調(diào)用,它可以訪問類中靜態(tài)的成員和靜態(tài)方法拴疤。
20.java中的析構(gòu)函數(shù)
Java中沒有像C/C++的析構(gòu)函數(shù)永部,用來銷毀不用的對象是否內(nèi)存空間,只有以下三個方法用于通知垃圾回收器回收對象呐矾。
(1).finalize( )只是通知JVM的垃圾收集器當前的對象不再使用可以被回收了苔埋,但是垃圾回收器根據(jù)內(nèi)存使用狀況來決定是否回收。
finalize()最有用的地方是在JNI調(diào)用本地方法時(C/C++方法)蜒犯,調(diào)用本地方法的析構(gòu)函數(shù)消耗對象釋放函數(shù)组橄。
(2). System.gc()是強制析構(gòu),顯式通知垃圾回收器釋放內(nèi)存罚随,但是垃圾回收器也不一定會立即執(zhí)行玉工,垃圾回收器根據(jù)當前內(nèi)存使用狀況和對象的生命周期自行決定是否回收。
(3).RunTime.getRunTime().gc()和System.gc()類似淘菩。
注意:這三個函數(shù)都不能保證垃圾回收器立即執(zhí)行遵班,推薦不要頻繁使用。
21.垃圾回收器原理
(1).引用計數(shù)(ReferenceCounting)垃圾回收算法:
一種簡單但是速度較慢的垃圾回收算法,每個對象擁有一個引用計數(shù)器(Reference Counter)狭郑,當每次引用附加到這個對象時腹暖,對象的引用計數(shù)器加1。當每次引用超出作用范圍或者被設置為null時愿阐,對象的引用計數(shù)器減1微服。垃圾回收器遍歷整個對象列表,當發(fā)現(xiàn)一個對象的引用計數(shù)器為0時缨历,將該對象移出內(nèi)存釋放以蕴。
引用計數(shù)算法的缺點是,當對象環(huán)狀相互引用時辛孵,對象的引用計數(shù)器總不為0丛肮,要想回收這些對象需要額外的處理。
引用計數(shù)算法只是用來解釋垃圾回收器的工作原理魄缚,沒有JVM使用它實現(xiàn)垃圾回收器宝与。
引用計數(shù)的改進算法:
任何存活的對象必須被在靜態(tài)存儲區(qū)或者棧(Stack)中的引用所引用,因此當遍歷全部靜態(tài)存儲區(qū)或棧中的引用時冶匹,即可以確定所有存活的對象习劫。每當遍歷一個引用時,檢查該引用所指向的對象嚼隘,同時檢查該對象上的所有引用诽里,沒有引用指向的對象和相互自引用的對象將被垃圾回收器回收。
(2).暫停復制(stop-and-copy)算法:
垃圾回收器的收集機制基于:任何一個存活的對象必須要被一個存儲在椃捎迹或者靜態(tài)存儲區(qū)的引用所引用谤狡。
暫停復制的算法是:程序在運行過程中首先暫停執(zhí)行,把每個存活的對象從一個堆復制到另一個堆中卧檐,已經(jīng)不再被使用的對象被回收而不再復制墓懂。
暫停復制算法有兩個問題:
a.必須要同時維護分離的兩個堆,需要程序運行所需兩倍的內(nèi)存空間霉囚。JVM的解決辦法是在內(nèi)存塊中分配堆空間捕仔,復制時簡單地從一個內(nèi)存塊復制到另一個內(nèi)存塊。
b.第二個問題是復制過程的本身處理盈罐,當程序運行穩(wěn)定以后逻澳,只會產(chǎn)生很少的垃圾對象需要回收,如果垃圾回收器還是頻繁地復制存活對象是非常低性能的暖呕。JVM的解決方法是使用一種新的垃圾回收算法——標記清除(mark-and-sweep)斜做。
一般來說標記清除算法在正常的使用場景中速度比較慢,但是當程序只產(chǎn)生很少的垃圾對象需要回收時湾揽,該算法就非常的高效瓤逼。
(3).標記清除(mark-and-sweep)算法:
和暫停復制的邏輯類似笼吟,標記清除算法從棧和靜態(tài)存儲區(qū)開始追蹤所有引用尋找存活的對象,當每次找到一個存活的對象時霸旗,對象被設置一個標記并且不被回收贷帮,當標記過程完成后,清除不用的死對象诱告,釋放內(nèi)存空間撵枢。
標記清除算法不需要復制對象,所有的標記和清除工作在一個內(nèi)存堆中完成精居。
注意:SUN的文檔中說JVM的垃圾回收器是一個后臺運行的低優(yōu)先級進程锄禽,但是在早期版本的JVM中并不是這樣實現(xiàn)的,當內(nèi)存不夠用時靴姿,垃圾回收器先暫停程序運行沃但,然后進行垃圾回收。
(4).分代復制(generation-copy)算法:
一種對暫停復制算法的改進佛吓,JVM分配內(nèi)存是按塊分配的宵晚,當創(chuàng)建一個大對象時,需要占用一塊內(nèi)存空間维雇,嚴格的暫停復制算法在釋放老內(nèi)存堆之前要求把每個存活的對象從源堆拷貝到新堆淤刃,這樣做非常的消耗內(nèi)存。
通過內(nèi)存堆吱型,垃圾回收器可以將對象拷貝到回收對象的內(nèi)存堆中逸贾,每個內(nèi)存塊擁有一個世代計數(shù)(generation count)用于標記對象是否存活。每個內(nèi)存塊通過對象被引用獲得世代計數(shù)唁影,一般情況下只有當最老的內(nèi)存塊被回收時才會創(chuàng)建新的內(nèi)存塊,這主要用于處理大量的短存活周期臨時對象回收問題掂名。一次完整的清理過程中据沈,內(nèi)存塊中的大對象不會被復制,只是根據(jù)引用重新獲得世代計數(shù)饺蔑。
JVM監(jiān)控垃圾回收器的效率锌介,當發(fā)現(xiàn)所有的對象都是長時間存活時,JVM將垃圾回收器的收集算法調(diào)整為標記清除猾警,當內(nèi)存堆變得零散碎片時孔祸,JVM又重新將垃圾回收器的算法切換會暫停復制,這就是JVM的自適應分代暫停復制標記清除垃圾回收算法的思想发皿。
22.java即時編譯技術(JIT)
Java的JIT是just-in-timecomplier技術崔慧,JIT技術是java代碼部分地或全部轉(zhuǎn)換成本地機器碼程序,不再需要JVM解釋穴墅,執(zhí)行速度更快惶室。
當一個”.class”的類文件被找到時温自,類文件的字節(jié)碼被調(diào)入內(nèi)存中,這時JIT編譯器編譯字節(jié)碼代碼皇钞。
JIT有兩個不足:
(1).JIT編譯轉(zhuǎn)換需要花費一些時間悼泌,這些時間貫穿于程序的整個生命周期。
(2).JIT增加了可執(zhí)行代碼的size夹界,相比于壓縮的字節(jié)碼馆里,JIT代碼擴展了代碼的size,這有可能引起內(nèi)存分頁可柿,進而降低程序執(zhí)行速度鸠踪。
對JIT不足的一種改進技術是延遲評估(lazy evaluation):其基本原理是字節(jié)碼并不立即進行JIT編譯除非必要,在最近的JDK中采用了一種類似延遲JIT的HotSpot方法對每次執(zhí)行的代碼進行優(yōu)化趾痘,代碼執(zhí)行次數(shù)越多慢哈,速度越快。
23.非內(nèi)部類的訪問控制權(quán)限只能是默認的包訪問權(quán)限或者是public的永票,不能是protected和private的卵贱。內(nèi)部類的訪問控制權(quán)限可以是protected和private。
24.Java中的高精度數(shù)值類型
BigInteger和BigDecimal是java中的高精度數(shù)值類型侣集,由于它們是用于包裝java的基本數(shù)據(jù)類型键俱,因此這兩個高精度數(shù)值類型沒有對應的原始類型。
(1).BigInteger支持任意精度的整數(shù)世分,即使用BigInteger可以表示任意長度的整數(shù)值而在運算中不會因為范圍溢出丟失信息编振。
(2).BigDecimal支持任意精度的固定位數(shù)浮點數(shù),可以用來精確計算貨幣等數(shù)值臭埋。
普通的float和double型浮點數(shù)因為受到小數(shù)點位數(shù)限制踪央,在運算時不能準確比較,只能以誤差范圍確定是否相等瓢阴,而BigDecimal就可以支持固定位數(shù)的浮點數(shù)并進行精確計算畅蹂。