第一篇:Java讀書筆記
讀書筆記
1、類和對(duì)象:類是用來定義一組對(duì)象共同具有的狀態(tài)和行為的模版。而對(duì)象是現(xiàn)實(shí)世界中個(gè)體或事物的抽象表示,并且封裝了它們的屬性和行為。
2、為了防止命名沖突,Java采用了管理類文件的機(jī)制,即類包機(jī)制。(package)定義包名的語法格式:
“package包名;”
Java命名規(guī)則要求包的命名需要使用小寫字母。
3、成員變量和成員方法:
1成員變量是在類體中定義的變量即全局變量,○成員變量一般用于定義對(duì)象的狀態(tài)。成員變量是給對(duì)象使用的,每個(gè)對(duì)象被創(chuàng)建后都會(huì)有屬于自己的屬性,即成員變量。通過修改這些屬性,從而改變對(duì)象的某個(gè)狀態(tài)。
2成員方法是對(duì)象行為的描述?!?/p>
定義成員方法的語法格式:
“[修飾符] 返回值類型方法名([形參表]){
······//方法體
}”
修飾符:可以是:publicprivateprotactedstaticfinall等;
返回值類型:如果方法需要返回值,必須這里聲明方法的返回值類型,可以是基
本數(shù)據(jù)類型(int short double booleanvoid等),也可以是對(duì)象
類型如:數(shù)組、字符串等。
形參表:(可選部分)說明方法被調(diào)用時(shí)應(yīng)該向它傳遞的數(shù)據(jù)。形參表可以有一
個(gè)也可以有多個(gè),當(dāng)有多個(gè)形參時(shí)每個(gè)形參之間要用“,”隔開。
1創(chuàng)建對(duì)象:創(chuàng)建對(duì)象使用到new語句。
4、對(duì)象:○
聲明并創(chuàng)建對(duì)象的語法格式如下:
“類名對(duì)象名=new 類構(gòu)造方法()”
構(gòu)造方法:構(gòu)造方法是類創(chuàng)建對(duì)象是必須執(zhí)行的方法,用于構(gòu)造一個(gè)新的對(duì)象并
初始化對(duì)象屬性。
2訪問對(duì)象的屬性: ○
語法格式:
“對(duì)象名.屬性”
3執(zhí)行對(duì)象的行為:○對(duì)象的行為就是對(duì)象的成員方法,通常說調(diào)用或執(zhí)行對(duì)象的某個(gè)方法。
語法格式:
“對(duì)象名.成員方法名();”
4對(duì)象的銷毀:Java提供了垃圾回收機(jī)制,對(duì)不再使用的對(duì)象會(huì)自動(dòng)銷毀,也可○
以在程序中顯式的為某個(gè)對(duì)象賦null值,使對(duì)象不再被使用。
垃圾回收機(jī)制會(huì)找到并銷毀它,釋放該對(duì)象所占用的資源。
語法格式:
“對(duì)象名=null”
1創(chuàng)建類:Java中使用class關(guān)鍵字來創(chuàng)建類。
5、類:○
聲明并創(chuàng)建類的語法格式:
“權(quán)限修飾符 class類名{
類體;
}”
權(quán)限修飾符:(可選項(xiàng))可以使用public protected private 或者省略這3者。類體主要由成員變量和方法兩部分組成。
2成員變量:在Java中對(duì)象的屬性也稱為成員變量。○
聲明并創(chuàng)建成員變量的語法格式:
“權(quán)限修飾符數(shù)據(jù)類型成員變量名;”
(用static關(guān)鍵字定義的成員變量被稱為靜態(tài)成員變量即類變量。靜態(tài)成員變量不是分配給每個(gè)對(duì)象的,而是屬于累的變量。它在內(nèi)存中是唯一的,可以直接使用“類名.成員變量名”的格式去訪問,他在內(nèi)存中的位置是固定的,是該類的所有實(shí)例對(duì)象所共享的存儲(chǔ)單元。)
3成員方法:在Java語言中使用成員方法對(duì)應(yīng)與類對(duì)象的行為?!?/p>
定義成員方法的語法格式:
“權(quán)限修飾符返回值類型方法名(參數(shù)類型參數(shù)名){
·······//方法體
}”
(同類變量一樣,由static關(guān)鍵字定義的成員方法被稱為類方法,類方法可以不必創(chuàng)建對(duì)象而由類直接訪問,靜態(tài)方法不可以直接調(diào)用非靜態(tài)方法)4局部變量:○在方法體中聲明的變量為局部變量,局部變量的有效范圍為方法體結(jié)束。
5this關(guān)鍵字:在Java語言中用this關(guān)鍵字來代表類對(duì)象的引用,this關(guān)鍵字被○
隱式地用于引用對(duì)象的成員變量和方法。(在類方法中不可以使用this關(guān)鍵字。)this關(guān)鍵字和和對(duì)象都可以調(diào)用成員變量和方法,兩者的區(qū)別:
事實(shí)上,this引用的就是本類的一個(gè)對(duì)象,在局部變量或方法參數(shù)覆蓋了成員變量時(shí),就要添加this關(guān)鍵字明確引用的是類成員還是局部變量的方法參數(shù)。6類的構(gòu)造方法:構(gòu)造方法與類同名?!?/p>
7類的主方法:主方法是類的入口點(diǎn),它定義了程序從何處開始;主方法提供對(duì)○
程序流向的控制,Java編譯器通過主方法來執(zhí)行程序。
1)主方法是靜態(tài)的,所以如果要直接在主方法體中
調(diào)用其他方法,則該方法必須也是靜態(tài)的。
2)主方法沒有返回值。
3)主方法的形參為數(shù)組。其中args[0]~args[n]分別
代表程序的第一個(gè)參數(shù)到第n個(gè)參數(shù),可以使用
args.length獲取參數(shù)的個(gè)數(shù)。
Java中完整的類聲明格式:
“權(quán)限修飾符class類名{
權(quán)限修飾符數(shù)據(jù)類型成員變量名1;
權(quán)限修飾符數(shù)據(jù)類型成員變量名2;
·······
權(quán)限修飾符數(shù)據(jù)類型成員變量名n;
權(quán)限修飾符返回值類型成員方法名1(形參類型形參變量){ 方法體
}
權(quán)限修飾符返回值類型成員方法名2(形參類型形參變量){ 方法體
}
······
權(quán)限修飾符返回值類型成員方法名n(形參類型形參變量){ 方法體
} }”
6.由于類的主方法是靜態(tài)方法所以不可以調(diào)用類中的非靜態(tài)方法所以當(dāng)需要調(diào)用非靜態(tài)方法時(shí)必須創(chuàng)建對(duì)象來調(diào)用。在輸入不同類型的數(shù)據(jù)時(shí)要使用不同的Scanner類對(duì)象,否則只能實(shí)現(xiàn)輸入一種數(shù)據(jù)類型。
7.abstract關(guān)鍵字是定義抽象類的關(guān)鍵字。使用abstract定義的發(fā)放成為抽象方法。抽象方法沒有方法體。抽象方法的唯一意義就是被重載。
第二篇:java高級(jí)Inside_JVM讀書筆記
本文首先介紹一下Java虛擬機(jī)的生存周期,然后大致介紹JVM的體系結(jié)構(gòu),最后對(duì)體系結(jié)構(gòu)中的各個(gè)部分進(jìn)行詳細(xì)介紹。
(首先這里澄清兩個(gè)概念:JVM實(shí)例和JVM執(zhí)行引擎實(shí)例,JVM實(shí)例對(duì)應(yīng)了一個(gè)獨(dú)立運(yùn)行的java程序,而JVM執(zhí)行引擎實(shí)例則對(duì)應(yīng)了屬于用戶運(yùn)行程序的線程;也就是JVM實(shí)例是進(jìn)程級(jí)別,而執(zhí)行引擎是線程級(jí)別的。)
一、JVM的生命周期
JVM實(shí)例的誕生:當(dāng)啟動(dòng)一個(gè)Java程序時(shí),一個(gè)JVM實(shí)例就產(chǎn)生了,任何一個(gè)擁有public static void main(String[] args)函數(shù)的class都可以作為JVM實(shí)例運(yùn)行的起點(diǎn),既然如此,那么JVM如何知道是運(yùn)行class A的main而不是運(yùn)行class B的main呢?這就需要顯式的告訴JVM類名,也就是我們平時(shí)運(yùn)行java程序命令的由來,如java classA hello world,這里java是告訴os運(yùn)行Sun java 2 SDK的java虛擬機(jī),而classA則指出了運(yùn)行JVM所需要的類名。
JVM實(shí)例的運(yùn)行:main()作為該程序初始線程的起點(diǎn),任何其他線程均由該線程啟動(dòng)。JVM內(nèi)部有兩種線程:守護(hù)線程和非守護(hù)線程,main()屬于非守護(hù)線程,守護(hù)線程通常由JVM自己使用,java程序也可以標(biāo)明自己創(chuàng)建的線程是守護(hù)線程。
JVM實(shí)例的消亡:當(dāng)程序中的所有非守護(hù)線程都終止時(shí),JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出。
二、JVM的體系結(jié)構(gòu)
粗略分來,JVM的內(nèi)部體系結(jié)構(gòu)分為三部分,分別是:類裝載器(ClassLoader)子系統(tǒng),運(yùn)行時(shí)數(shù)據(jù)區(qū),和執(zhí)行引擎。
下面將先介紹類裝載器,然后是執(zhí)行引擎,最后是運(yùn)行時(shí)數(shù)據(jù)區(qū)
1,類裝載器,顧名思義,就是用來裝載.class文件的。JVM的兩種類裝載器包括:啟動(dòng)類裝載器和用戶自定義類裝載器,啟動(dòng)類裝載器是JVM實(shí)現(xiàn)的一部分,用戶自定義類裝載器則是Java程序的一部分,必須是ClassLoader類的子類。(下面所述情況是針對(duì)Sun JDK1.2)
動(dòng)類裝載器:只在系統(tǒng)類(java API的類文件)的安裝路徑查找要裝入的類
用戶自定義類裝載器:
系統(tǒng)類裝載器:在JVM啟動(dòng)時(shí)創(chuàng)建,用來在CLASSPATH目錄下查找要裝入的類
其他用戶自定義類裝載器:這里有必要先說一下ClassLoader類的幾個(gè)方法,了解它們對(duì)于了解自定義類裝載器如何裝載.class文件至關(guān)重要。
protected final Class defineClass(String name, byte data[], int offset, int length)
protected final Class defineClass(String name, byte data[], int offset, int length, ProtectionDomain protectionDomain);
protected final Class findSystemClass(String name)
protected final void resolveClass(Class c)
defineClass用來將二進(jìn)制class文件(新類型)導(dǎo)入到方法區(qū),也就是這里指的類是用戶自定義的類(也
就是負(fù)責(zé)裝載類)
findSystemClass通過類型的全限定名,先通過系統(tǒng)類裝載器或者啟動(dòng)類裝載器來裝載,并返回
Class對(duì)象。
ResolveClass: 讓類裝載器進(jìn)行連接動(dòng)作(包括驗(yàn)證,分配內(nèi)存初始化,將類型中的符號(hào)引用解析為
直接引用),這里涉及到j(luò)ava命名空間的問題,JVM保證被一個(gè)類裝載器裝載的類所引用的所有類都被這個(gè)類裝載器裝載,同一個(gè)類裝載器裝載的類之間可以相互訪問,但是不同類裝載器裝載的類看不見對(duì)方,從而實(shí)現(xiàn)了有效的屏蔽。
2,執(zhí)行引擎:它或者在執(zhí)行字節(jié)碼,或者執(zhí)行本地方法
要說執(zhí)行引擎,就不得不的指令集,每一條指令包含一個(gè)單字節(jié)的操作碼,后面跟0個(gè)或者多個(gè)
操作數(shù)。
(一)指令集以棧為設(shè)計(jì)中心,而非以寄存器為中心
這種指令集設(shè)計(jì)如何滿足Java體系的要求:
平臺(tái)無關(guān)性:以棧為中心使得在只有很少register的機(jī)器上實(shí)現(xiàn)java更便利
compiler一般采用stack向連接優(yōu)化器傳遞編譯的中間結(jié)果,若指令集以stack為基礎(chǔ),則有利于運(yùn)行
時(shí)進(jìn)行的優(yōu)化工作與執(zhí)行即時(shí)編譯或者自適應(yīng)優(yōu)化的執(zhí)行引擎結(jié)合,通俗的說就是使編譯和運(yùn)行用的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一,更有利于優(yōu)化的開展。
網(wǎng)絡(luò)移動(dòng)性:class文件的緊湊性。
安全性:指令集中絕大部分操作碼都指明了操作的類型。(在裝載的時(shí)候使用數(shù)據(jù)流分析期進(jìn)行一
次性驗(yàn)證,而非在執(zhí)行每條指令的時(shí)候進(jìn)行驗(yàn)證,有利于提高執(zhí)行速度)。
(二)執(zhí)行技術(shù)
主要的執(zhí)行技術(shù)有:解釋,即時(shí)編譯,自適應(yīng)優(yōu)化、芯片級(jí)直接執(zhí)行
其中解釋屬于第一代JVM,即時(shí)編譯JIT屬于第二代JVM,自適應(yīng)優(yōu)化(目前Sun的HotspotJVM
采用這種技術(shù))則吸取第一代JVM和第二代JVM的經(jīng)驗(yàn),采用兩者結(jié)合的方式
自適應(yīng)優(yōu)化:開始對(duì)所有的代碼都采取解釋執(zhí)行的方式,并監(jiān)視代碼執(zhí)行情況,然后對(duì)那些經(jīng)常調(diào)
用的方法啟動(dòng)一個(gè)后臺(tái)線程,將其編譯為本地代碼,并進(jìn)行仔細(xì)優(yōu)化。若方法不再頻繁使用,則取消編譯過的代碼,仍對(duì)其進(jìn)行解釋執(zhí)行。
3,運(yùn)行時(shí)數(shù)據(jù)區(qū):主要包括:方法區(qū),堆,java棧,PC寄存器,本地方法棧
(1)方法區(qū)和堆由所有線程共享
堆:存放所有程序在運(yùn)行時(shí)創(chuàng)建的對(duì)象
方法區(qū):當(dāng)JVM的類裝載器加載.class文件,并進(jìn)行解析,把解析的類型信息放入方法區(qū)。
(2)Java棧和PC寄存器由線程獨(dú)享,在新線程創(chuàng)建時(shí)間里
(3)本地方法棧: 存儲(chǔ)本地方法調(diào)用的狀態(tài)
上邊總體介紹了運(yùn)行時(shí)數(shù)據(jù)區(qū)的主要內(nèi)容,下邊進(jìn)行詳細(xì)介紹,要介紹數(shù)據(jù)區(qū),就不得不說明JVM
中的數(shù)據(jù)類型。
JVM中的數(shù)據(jù)類型:JVM中基本的數(shù)據(jù)單元是word,而word的長度由JVM具體的實(shí)現(xiàn)者來決定
數(shù)據(jù)類型包括基本類型和引用類型,(1)基本類型包括:數(shù)值類型(包括除boolean外的所有的java基本數(shù)據(jù)類型),boolean(在JVM中使
用int來表示,0表示false,其他int值均表示true)和returnAddress(JVM的內(nèi)部類型,用來實(shí)現(xiàn)
finally子句)。
(2)引用類型包括:數(shù)組類型,類類型,接口類型
前邊講述了JVM中數(shù)據(jù)的表示,下面讓我們輸入到JVM的數(shù)據(jù)區(qū)
首先來看方法區(qū):
上邊已經(jīng)提到,方法區(qū)主要用來存儲(chǔ)JVM從class文件中提取的類型信息,那么類型信息是如何存儲(chǔ)的呢?眾所周知,Java使用的是大端序(big—endian:即低字節(jié)的數(shù)據(jù)存儲(chǔ)在高位內(nèi)存上,如對(duì)于1234,12是高位數(shù)據(jù),34為低位數(shù)據(jù),則java中的存儲(chǔ)格式應(yīng)該為12存在內(nèi)存的低地址,34存在內(nèi)存的高地址,x86中的存儲(chǔ)格式與之相反)來存儲(chǔ)數(shù)據(jù),這實(shí)際上是在class文件中數(shù)據(jù)的存儲(chǔ)格式,但是當(dāng)數(shù)據(jù)倒入到方法區(qū)中時(shí),JVM可以以任何方式來存儲(chǔ)它。
類型信息:包括class的全限定名,class的直接父類,類類型還是接口類型,類的修飾符(public,等),所有直接父接口的列表,Class對(duì)象提供了訪問這些信息的窗口(可通過Class.forName(“”)或instance.getClass()獲得),下面是Class的方法,相信大家看了會(huì)恍然大悟,(原來如此?)
getName(), getSuperClass(), isInterface(), getInterfaces(), getClassLoader();
static變量作為類型信息的一部分保存
指向ClassLoader類的引用:在動(dòng)態(tài)連接時(shí)裝載該類中引用的其他類
指向Class類的引用:必然的,上邊已述
該類型的常量池:包括直接常量(String,integer和float point常量)以及對(duì)其他類型、字段和方法的符號(hào)引用(注意:這里的常量池并不是普通意義上的存儲(chǔ)常量的地方,這些符號(hào)引用可能是我們?cè)诰幊讨兴佑|到的變量),由于這些符號(hào)引用,使得常量池成為java程序動(dòng)態(tài)連接中至關(guān)重要的部分
字段信息:普通意義上的類型中聲明的字段
方法信息:類型中各個(gè)方法的信息
編譯期常量:指用final聲明或者用編譯時(shí)已知的值初始化的類變量
class將所有的常量復(fù)制至其常量池或者其字節(jié)碼流中。
方法表:一個(gè)數(shù)組,包括所有它的實(shí)例可能調(diào)用的實(shí)例方法的直接引用(包括從父類中繼承來的)除此之外,若某個(gè)類不是抽象和本地的,還要保存方法的字節(jié)碼,操作數(shù)棧和該方法的棧幀,異常表。舉例:
class Lava{
private int speed = 5;
void flow(){}
}
class Volcano{
public static void main(String[] args){
Lava lava = new Lava();
lava.flow();
}
}
運(yùn)行命令java Volcano;
(1)JVM找到Volcano.class倒入,并提取相應(yīng)的類型信息到方法區(qū)。通過執(zhí)行方法區(qū)中的字節(jié)碼,JVM
執(zhí)行main()方法,(執(zhí)行時(shí)會(huì)一直保存指向Vocano類的常量池的指針)
(2)Main()中第一條指令告訴JVM需為列在常量池第一項(xiàng)的類分配內(nèi)存(此處再次說明了常量池并非
只存儲(chǔ)常量信息),然后JVM找到常量池的第一項(xiàng),發(fā)現(xiàn)是對(duì)Lava類的符號(hào)引用,則檢查方法區(qū),看Lava類是否裝載,結(jié)果是還未裝載,則查找“Lava.class”,將類型信息寫入方法區(qū),并將方法區(qū)Lava類信息的指針來替換Volcano原常量池中的符號(hào)引用,即用直接引用來替換符號(hào)引用。
(3)JVM看到new關(guān)鍵字,準(zhǔn)備為Lava分配內(nèi)存,根據(jù)Volcano的常量池的第一項(xiàng)找到Lava在方法區(qū)的位置,并分析需要多少對(duì)空間,確定后,在堆上分配空間,并將speed變量初始為0,并將lava對(duì)象的引用壓到棧中
(4)調(diào)用lava的flow()方法
好了,大致了解了方法區(qū)的內(nèi)容后,讓我們來看看堆
java對(duì)象的堆實(shí)現(xiàn):
java對(duì)象主要由實(shí)例變量(包括自己所屬的類和其父類聲明的)以及指向方法區(qū)中類數(shù)據(jù)的指針,指向方法表的指針,對(duì)象鎖(非必需),等待集合(非必需),GC相關(guān)的數(shù)據(jù)(非必需)(主要視GC算法而定,如對(duì)于標(biāo)記并清除算法,需要標(biāo)記對(duì)象是否被引用,以及是否已調(diào)用finalize()方法)。
那么為什么java對(duì)象中要有指向類數(shù)據(jù)的指針呢?我們從幾個(gè)方面來考慮
首先:當(dāng)程序中將一個(gè)對(duì)象引用轉(zhuǎn)為另一個(gè)類型時(shí),如何檢查轉(zhuǎn)換是否允許?需用到類數(shù)據(jù)
其次:動(dòng)態(tài)綁定時(shí),并不是需要引用類型,而是需要運(yùn)行時(shí)類型,這里的迷惑是:為什么類數(shù)據(jù)中保存的是實(shí)際類型,而非引用類型?這個(gè)問題先留下來,我想在后續(xù)的讀書筆記中應(yīng)該能明白
指向方法表的指針:這里和C++的VTBL是類似的,有利于提高方法調(diào)用的效率
對(duì)象鎖:用來實(shí)現(xiàn)多個(gè)線程對(duì)共享數(shù)據(jù)的互斥訪問
等待集合:用來讓多個(gè)線程為完成共同目標(biāo)而協(xié)調(diào)功過。(注意Object類中的wait(),notify(),notifyAll()方法)。
Java數(shù)組的堆實(shí)現(xiàn):數(shù)組也擁有一個(gè)和他們的類相關(guān)聯(lián)的Class實(shí)例,具有相同dimension和type的數(shù)組是同一個(gè)類的實(shí)例。數(shù)組類名的表示:如[[Ljava/lang/Object 表示Object[][],[I表示int[],[[[B表示byte[][][]
至此,堆已大致介紹完畢,下面來介紹程序計(jì)數(shù)器和java棧
程序計(jì)數(shù)器:為每個(gè)線程獨(dú)有,在線程啟動(dòng)時(shí)創(chuàng)建,若thread執(zhí)行java方法,則PC保存下一條執(zhí)行指令的地址。
若thread執(zhí)行native方法,則Pc的值為undefined
Java棧:java棧以幀為單位保存線程的運(yùn)行狀態(tài),java棧只有兩種操作,幀的壓棧和出棧。
每個(gè)幀代表一個(gè)方法,java方法有兩種返回方式,return和拋出異常,兩種方式都會(huì)導(dǎo)致該方法對(duì)應(yīng)的幀出棧和釋放內(nèi)存。
幀的組成:局部變量區(qū)(包括方法參數(shù)和局部變量,對(duì)于instance方法,還要首先保存this類型,其中方法參數(shù)按照聲明順序嚴(yán)格放置,局部變量可以任意放置),操作數(shù)棧,幀數(shù)據(jù)區(qū)(用來幫助支持常量池的解析,正常方法返回和異常處理)。
本地方法棧:依賴于本地方法的實(shí)現(xiàn),如某個(gè)JVM實(shí)現(xiàn)的本地方法借口使用C連接模型,則本地方法棧就是C棧,可以說某線程在調(diào)用本地方法時(shí),就進(jìn)入了一個(gè)不受JVM限制的領(lǐng)域,也就是JVM可以利用本地方法來動(dòng)態(tài)擴(kuò)展本身。
第三篇:Java編程思想讀書筆記
這是一份試圖提綱挈領(lǐng)的讀書筆記,《java編程思想》這本八百多頁的書娓娓道來地包含了太多細(xì)節(jié),這對(duì)讀者是非常貼心的,我也強(qiáng)烈建議細(xì)細(xì)讀這本書,如果你希望在短時(shí)間內(nèi)學(xué)會(huì)java這種語言,那么這本書不是最好的選擇,你可以看看譚浩強(qiáng)系列。我把看這本書的過程中,個(gè)人覺得每一章中最重要的思想、用整理在這里,希望自己回顧的時(shí)候有所參照和提高。也希望大家?guī)е瑯拥哪康膩砜幢酒x書筆記。
第一章 對(duì)象導(dǎo)論
比起過程型語言編寫的程序,用面向?qū)ο笳Z言編寫的程序更加簡單、易于理解、可復(fù)用。《c++編程思想》里也有這一章,是一個(gè)拋磚引自己的玉的章節(jié),不明白可以跳過,回頭再看。
第二章 一切都是對(duì)象
java語言里面,一切都是對(duì)象,并且程序員是通過引用來操縱對(duì)象。一個(gè)簡單的例子,非常輕松地讓讀者進(jìn)入java的世界。需要注意的是java數(shù)據(jù)會(huì)儲(chǔ)存在5個(gè)不同的地方:寄存器、堆棧、堆、常量存儲(chǔ)、非ram存儲(chǔ),用new創(chuàng)建的一般對(duì)象都放在堆中,而特殊的基本對(duì)象放在堆棧中,如果想把基本對(duì)象也放在堆中,需要包裝基本類型。
第三章 操作符
java中的操作符語法類似于c,所以學(xué)習(xí)起來一點(diǎn)困難也沒有。要特別注意兩個(gè)比較大的整數(shù)相加或者相乘的時(shí)候的溢出問題,用long或者biginteger解決這個(gè)問題。
第四章 控制執(zhí)行流程
我想起《pointer on c》這本書第一章就有這一句話,本書適合那些希望迅速學(xué)習(xí)一門新語言而不是被“為什么if和for很重要”的弱智問題耽擱進(jìn)度的讀者。呵呵,這一章很不厭其煩地介紹了運(yùn)算、操作符優(yōu)先級(jí)、類型轉(zhuǎn)換、選擇循環(huán)等基本特性,有c或者c++編程經(jīng)驗(yàn)的讀者可以大概瀏覽一下。
第五章 初始化和清理
關(guān)于初始化:
1.初始化很重要,一定不要忘記。而且java編譯器會(huì)很好的防止使用未初始化數(shù)據(jù)的意外,這是比c和c++更優(yōu)的地方。
2.編譯器初始化的順序?yàn)椋?/p>
a.類首次加載的時(shí)候,有關(guān)靜態(tài)初始化的所有動(dòng)作都會(huì)執(zhí)行。
a1.類的加載包括首次創(chuàng)建該類型的對(duì)象,或者該類的靜態(tài)方法/靜態(tài)域首次被訪問
a2.靜態(tài)域的初始化在一切初始化之前,即靜態(tài)變量散布在代碼不同的地方,它們也會(huì)在任何方法(包括構(gòu)造器)調(diào)用之前被初始化
b.當(dāng)用new calssname()創(chuàng)建對(duì)象的時(shí)候,會(huì)在堆上開辟足夠的存儲(chǔ)空間,這塊存儲(chǔ)空間被清零,然后執(zhí)行字段的初始化動(dòng)作。(這里的字段初始化都是非靜態(tài)的,因?yàn)殪o態(tài)的變量已經(jīng)在a中執(zhí)行完畢,而且靜態(tài)變量存儲(chǔ)在不同的地方,靜態(tài)數(shù)據(jù)只占用一份存儲(chǔ)空間)
c.執(zhí)行構(gòu)造器
關(guān)于清理
c++關(guān)于清理的部分包含很大不確定性。目前需要知道的事情是,正常情況下,我們是不需要調(diào)用finalize方法的,而且垃圾回收區(qū)會(huì)自動(dòng)回收不再使用的對(duì)象,同時(shí)我們需要自己注意一些需要關(guān)閉的文件。
需要注意的是,用=對(duì)數(shù)組進(jìn)行“賦值”的時(shí)候,實(shí)際上是引用的傳遞,就是說,二者指向同一堆。
第六章 訪問權(quán)限控制
關(guān)于包
你應(yīng)該有一個(gè)自己的域名,這樣發(fā)布你的java程序的時(shí)候,就可以將你的包名設(shè)置為你的域名倒轉(zhuǎn)。想要正確讓包工作,要正確設(shè)置classpath,對(duì)于新手來說,這的確是一個(gè)挑戰(zhàn)。我當(dāng)初就難到了。
關(guān)于訪問權(quán)限修飾詞
值得注意的是,如果兩個(gè)編譯單元放在同一個(gè)目錄下并且都沒有設(shè)置包名的話,他們對(duì)于對(duì)方都是擁有包訪問權(quán)限的。訪問權(quán)限修飾詞是修飾方法和數(shù)據(jù),而不是類。類只有兩種訪問權(quán)限,包訪問權(quán)限或public訪問權(quán)限。默認(rèn)為包訪問權(quán)限。如果不希望其它任何人對(duì)該類擁有訪問權(quán)限,可以把所有的構(gòu)造器設(shè)置為private。但是有一個(gè)例外,可以通過該類自己的static成員內(nèi)部創(chuàng)建(于是就有了工廠設(shè)計(jì)模式和單例設(shè)計(jì)模式)。
第七章 復(fù)用類
有三種方法復(fù)用類:組合,繼承,代理。
組合即是在新的類里面放上已經(jīng)定義的類的對(duì)象,然后通過調(diào)用它的方法來實(shí)現(xiàn)自己的功能。
繼承是通過extends關(guān)鍵詞繼承某一父類,這樣就能訪問父類的所有public方法(因此為了繼承,一般的規(guī)則是將父類的所有數(shù)據(jù)成員都指定為private,將所有的方法都指定為public)。子類的初始化需要注意的是,(當(dāng)創(chuàng)建了一個(gè)子類的對(duì)象時(shí),該對(duì)象包含一個(gè)基類的子對(duì)象)java會(huì)在子類的構(gòu)造器中插入對(duì)基類默認(rèn)構(gòu)造器的調(diào)用。但是如果沒有默認(rèn)的基類構(gòu)造器,或者想調(diào)用一個(gè)帶參數(shù)的基類構(gòu)造器,就必須用關(guān)鍵詞super顯式地編寫調(diào)用基類構(gòu)造器的語句,并且配上適當(dāng)?shù)膮?shù)列表。
代理很有意思,(我們姑且使用導(dǎo)出類和基類這樣的字眼,但要清楚我們不是在討論繼承里面的關(guān)鍵詞)在導(dǎo)出類里保存一個(gè)基類的對(duì)象,然后用自己的方法對(duì)該基類的種種方法進(jìn)行包裝。
如何決定使用哪種方法復(fù)用類呢?is-a就繼承,has-a就用組合。而且,組合比繼承總體上使用更廣泛、代價(jià)更小。
向上轉(zhuǎn)型
這個(gè)就牛逼了,第八章,第九章,第十章都與此密切相關(guān)??赐瓯緯笥∠笞钌畹木褪窍蛏限D(zhuǎn)型了。
使用final的原因有很多種,一定要弄清楚為什么使用final,是由于設(shè)計(jì)還是效率。
final作用于數(shù)據(jù)的時(shí)候:final作用在基本對(duì)象比如int上,該值就成為不可改變的,一旦被初始化就無法再被更改,但是作用在普通的對(duì)象引用的時(shí)候,final使引用恒定不變,但是引用指向的對(duì)象是可變的。編譯器需要我們確保final對(duì)象一定要被初始化,我們可以通過在構(gòu)造器中初始化他們,以達(dá)到相對(duì)自由的效果(稱為空白final,我認(rèn)為這個(gè)名字容易讓人誤解)。java允許在參數(shù)列表中以聲明的方式將參數(shù)指明為final,這一特性主要用來向匿名內(nèi)部類傳遞數(shù)據(jù)(這很重要)。
final作用于方法的時(shí)候,說明作者想保持該方法在繼承的過程中不被改變,并且不被覆蓋。同時(shí),被final修飾的方法會(huì)被關(guān)閉“動(dòng)態(tài)綁定”,這樣編譯器就會(huì)為final方法調(diào)用生成“有限”有效的代碼。之所以說有限,是因?yàn)殡S著編譯器的牛逼,它生成的代碼越來越有效。
final作用于類的時(shí)候,即是作者聲明對(duì)該類的設(shè)計(jì)不允許任何繼承。
學(xué)習(xí)得更深入一些,可能對(duì)以下事實(shí)感到有興趣:java中所有的事物都是對(duì)象,每個(gè)類的編譯代碼都存在于電腦中的文件夾里(文件夾的層次根據(jù)反轉(zhuǎn)域名得到),該文件只有在需要使用程序代碼時(shí)才被加載。具體的說,就是“類在其任何static成員函數(shù)(包括構(gòu)造函數(shù))被訪問時(shí)加載”。第八章 多態(tài)
多態(tài)的重要基本原理就是向上轉(zhuǎn)型:繼承允許將對(duì)象視為它自己本身的類型或其基類型加以處處理。
將一個(gè)方法調(diào)用和一個(gè)方法主題關(guān)聯(lián)起來稱為綁定,java中所有的方法都是后期綁定(除了static方法和final方法),所以我們可以編寫只與基類打交道的程序代碼,并且這些代碼對(duì)所有的導(dǎo)出類都可以正確運(yùn)行。
(為什么static不動(dòng)態(tài)綁定:因?yàn)閟tatic方法的主要用法就是用類名.方法名這樣的方式來調(diào)用,不存在“發(fā)送消息給某個(gè)對(duì)象,讓對(duì)象判斷自己怎么做”這樣的情況。
為什么final不動(dòng)態(tài)綁定:這是早期final的一種用法,由程序員指定某方法為final,意味著程序員明了動(dòng)態(tài)綁定的機(jī)制,并且聲明該方法不需要?jiǎng)討B(tài)綁定,這樣可以獲得更好的性能。這種用法已經(jīng)很少使用了。)
初始化的時(shí)候,導(dǎo)出類的構(gòu)造函數(shù)會(huì)自動(dòng)調(diào)用基類的默認(rèn)構(gòu)造函數(shù),此過程一直遞歸到最基本的基類。如果需要調(diào)用有參數(shù)的構(gòu)造函數(shù)就需要手動(dòng)執(zhí)行。反過來,如果需要進(jìn)行清理工作(大部分時(shí)候我們都不需要),務(wù)必手動(dòng)執(zhí)行基類的清理工作先。比如繼承鏈的每個(gè)類都實(shí)現(xiàn)dispose()方法,那么執(zhí)行某個(gè)類的清理工作的時(shí)候,需要手動(dòng)調(diào)用super.dispose()。不過此種情況下,務(wù)必在執(zhí)行super.dispose()之前釋放成員對(duì)象,清理順序與執(zhí)行順序是相反的。
此外,構(gòu)造器方面有更加復(fù)雜的調(diào)用機(jī)制,我們不用理它,只需要知道一條有效的準(zhǔn)則“用盡可能簡單的方法使對(duì)象進(jìn)入正常狀態(tài),如果可以的話避免調(diào)用其它方法”。
java編譯器能夠允許向上多態(tài),就是因?yàn)閖ava的機(jī)制能保存對(duì)象的類型信息,即rtti,正因?yàn)檫@種機(jī)制,java編譯器也允許向下轉(zhuǎn)型,以獲得擴(kuò)展類的“擴(kuò)展出”的方法。(另,擴(kuò)展類“擴(kuò)展”了方法的這種繼承不是“純繼承”,這樣做好不好?用戶自己度量)。向下轉(zhuǎn)型失敗的話會(huì)拋出一個(gè)classcastexception。
雖然這一章都是在講多態(tài),但是多態(tài)并不總是解決問題最好的方案,它有可能使事情不必要地復(fù)雜起來,我們應(yīng)該總是優(yōu)先考慮更加靈活的組合。
第九章 接口
一種專門提供“接口”的類叫抽象類,若含有至少一個(gè)abstract方法,該類就必須被聲明為abstract的。抽象方法沒有方法體,派生類必須實(shí)現(xiàn)它,否則派生類也必須被生命為抽象的。
interface關(guān)鍵詞使抽象的概念更進(jìn)了一步:1.這個(gè)“類”完全抽象。2.一個(gè)類可以向上轉(zhuǎn)型為多種interface。要讓一個(gè)類遵循某個(gè)特定接口,需要使用implement關(guān)鍵字。
在這一章中出現(xiàn)了“策略設(shè)計(jì)模式”這個(gè)詞。創(chuàng)建一個(gè)能夠根據(jù)所傳遞的參數(shù)對(duì)象的不同而具有不同行為的方法,被稱為策略設(shè)計(jì)模式。
策略設(shè)計(jì)模式跟適配器設(shè)計(jì)模式聯(lián)合使用可以提供非常強(qiáng)大的功能,比如我們遇到了無法更改的類(別人編寫的),想要它滿足我們的接口然后放到設(shè)計(jì)模式里面去(當(dāng)然滿足了接口之后的用法就不止如此了),就可以編寫一個(gè)適配器,包裝該類同時(shí)產(chǎn)生我所需要的接口。
使用抽象類和接口的兩個(gè)原因是:1.在多重繼承關(guān)系中(這真的很常見,看看java api就知道了),導(dǎo)出類可以被向上轉(zhuǎn)型為每一個(gè)接口。2.防止客戶端程序員創(chuàng)建該類的對(duì)象。那么我們?cè)撌褂贸橄箢愡€是接口呢?事實(shí)上,如果知道某事物應(yīng)該成為一個(gè)基類,那么第一選擇應(yīng)該是使它成為一個(gè)接口。
接口之間的繼承能夠形成很好的體系,更像我們的現(xiàn)實(shí)生活。但是要特別注意的是,在不同接口中使用相同的方法名通常會(huì)造成代碼可讀性的混亂,令人不快。
工廠方法設(shè)計(jì)模式是又一個(gè)重要的設(shè)計(jì)模式。我們?cè)诖a中增加額外的間接性,一個(gè)重要的原因是想要?jiǎng)?chuàng)建框架。
第四篇:讀書筆記《Java郵件開發(fā)詳解》
讀書筆記《Java郵件開發(fā)詳解》
DNS
MX
自動(dòng)回復(fù) 不填from 避免循環(huán)回復(fù)。
Pop3:可以查郵件總數(shù)、已占空間。
電子郵件的RFC822格式:
Return-Path:代表郵件的回復(fù)地址,該字段的內(nèi)容由接收郵件的SMTP服務(wù)器填寫,接收郵件的SMTP服務(wù)器從郵件發(fā)送程序發(fā)出的mail form命令中獲得內(nèi)容。
Received:通常格式是:Received from A by B for C,A為發(fā)送方,B為接收方,C為收件人的郵箱地址。常常被用來追蹤?quán)]件傳輸?shù)穆肪€和分析郵件的來源。From:
To:
Subject:
Date:
Cc:
Bcc:
郵件的頭字段可以擴(kuò)充成MIME類型。Content-Type: multipart/mixed;頭字段指定編碼方法。另外,也定義了郵件頭字段的內(nèi)涵。
MIME消息的頭字段具體資源的數(shù)據(jù)類型和組合消息的組合關(guān)系,都是通過消息頭中的Content-Type頭字段來指定的,格式為“主類型/子類型”的形式出現(xiàn),主類型有text、image、audio、application、multipart、message等;每個(gè)主類型下面又都有好多子類型。
MIME消息可以有三種組合關(guān)系:
Multipart/mixed 混合組合 內(nèi)容可以是文本、附件等等。
Multipart/related 關(guān)聯(lián)組合 如郵件正文要使用HTML代碼引用內(nèi)嵌的圖片資源。意思是說某些資源要關(guān)聯(lián)引用另外的資源。
Multipart/alternative 選擇組合這三種關(guān)系是可以隨意嵌套的,比如你寄一個(gè)復(fù)雜的盒子出去,這個(gè)盒子里面可以有好多好多小盒子,而每個(gè)盒子都可以看作一個(gè)MIME。
其他的頭字段都是顧名思義的,略!
設(shè)置內(nèi)容的另一種方法:
setContent(Object object, String type)
setContent(body, “text/html;charset=gb2312”);
另外一種客戶端的發(fā)信方式:SMTP服務(wù)器功能的郵件發(fā)送程序
具有SMTP服務(wù)器功能的郵件發(fā)送程序會(huì)根據(jù)收件人地址的域名,直接連接到該域的SMTP服務(wù)器和進(jìn)行郵件發(fā)送。根本用不到??
JNDI:命名式:把對(duì)象綁定到context中;目錄式:保存對(duì)象的屬性信息實(shí)際應(yīng)用中命名式和對(duì)象式常常結(jié)合使用。
Tomcat可以通過配置文件自己創(chuàng)建javax.mail.Session
META-INF/context.xml
auth=”Container” type=”javax.mail.Session” mail.smtp.host=”smtp.sina.com.cn” mail.transport.protool=”smtp” mail.smtp.auth=”true” /> 在web.xml中說明一下,有資源是被tomcat創(chuàng)建的,如果換了別的應(yīng)用服務(wù)器也要?jiǎng)?chuàng)建。 不知道書上為什么費(fèi)那么大勁找個(gè)Session出來,還是個(gè)沒有校驗(yàn)的Session,收發(fā)郵件時(shí)都得再寫用戶名密碼給服務(wù)器。為什么不隨便new一個(gè)或者從System中調(diào)一個(gè)呢?感覺基本用不著,我自己寫一個(gè)properties文件豈不是更好? JAF 對(duì)于通過JAF封裝的數(shù)據(jù),應(yīng)用程序通過JAF提供的接口可以完成如下功能:。訪問數(shù)據(jù)源中的數(shù)據(jù) 。獲知數(shù)據(jù)源的數(shù)據(jù)類型 。獲知可對(duì)數(shù)據(jù)源進(jìn)行的各種操作 。用戶對(duì)數(shù)據(jù)源執(zhí)行某種操作時(shí),自動(dòng)創(chuàng)建執(zhí)行該操作的軟件部件的實(shí)例對(duì)象 好像是用來封裝數(shù)據(jù)源的(比如:聲音文件,java文件),這樣的好處是?可以識(shí)別文件類型對(duì)文件直接操作?不知道,回頭再看看。好像是附件用的,ms。 郵件搜索 用于創(chuàng)建邏輯組合關(guān)系的類AND、OR、NOT、Comparison 用于創(chuàng)建具體搜索條件的類DATE、CONTENT、HEADER 例:SearchTerm st = new AndTerm(new FromStringTerm(“zx@sina.com”),new ReceivedDateTerm(ComparisonTerm.EQ, new Date())); 這里主要說明ComparisonTerm類,常用于日期類的比較其中使用留個(gè)常量來標(biāo)識(shí)六種不同的操作:EQ(=)、GE(>=)、GT(>)、LE(<=)、LT(<)、NE(!=)郵件的解析與顯示 如果Message的類型是“text/*”直接顯示之。如果Message的類型 (getContentType())是“multipart/mixed”,調(diào)getContent()方法得到Multipart,對(duì)其調(diào)getCount()看看其中有多少個(gè)BodyPart,遍歷之;當(dāng)MIME類型為“text/*”顯示之,當(dāng)MIME是圖片、聲音或附件等二進(jìn)制時(shí),調(diào) getDataHandler方法得到封裝數(shù)據(jù)的對(duì)象,然后調(diào)其getInputSteam??.;當(dāng)MIME類型為“mutlipart/mixed”再次遍歷得到其中的BodyPart。 注意:Message.isMimeType(“multipart/*”)這個(gè)方法居然可以寫通配附?!看看API的解釋:If the subType of mimeType is the special character '*', then the subtype is ignored during the comparison.。 處理內(nèi)嵌類型的multipart(multipart/related)直接交給IE瀏覽器去顯示就好了: response.setContentType(”message/rfc822”); message.writeTo(response.getOutputStream()); 總結(jié): 總的來說這本書講的很基礎(chǔ),前半部分告訴我們什么是email、email是如何收發(fā)的及email的格式、著重說明了smtp協(xié)議和pop3協(xié)議,甚至告訴大家怎么使用協(xié)議的命令收發(fā)郵件,這些對(duì)于使用API做web開發(fā)的程序員來說用處不是很大,但第3章郵件的組織結(jié)構(gòu)講述的還是比較好的;后半部分主要對(duì)Javamail進(jìn)行說明,但是我個(gè)人覺得不如IBM的在線教程介紹的實(shí)用,主要是例子寫的別扭,呵呵。不過里面有一些細(xì)節(jié)可以起到拓寬知識(shí)面的作用。 此書對(duì)開發(fā)webmail用處不是很大,比如對(duì)于pop3協(xié)議來說,如何標(biāo)記郵件,如何建立文件夾,如何移動(dòng)郵件,甚至通訊錄什么的都一點(diǎn)也沒有提到,講郵件搜索的時(shí)候沒有說郵件過濾能不能通過搜索實(shí)現(xiàn)或者還是有更好的辦法。更深入一點(diǎn)的比如用工廠模式解耦合、使用線程池提高性能等更是只字未提。哎~看來還得再找找,實(shí)在不行就操作數(shù)據(jù)庫,那樣麻煩很多但是應(yīng)該什么都能實(shí)現(xiàn)。最近看webmail看的很不爽,網(wǎng)上這樣的東西也很少,感覺沒有一個(gè)套路...郁悶~~ 一 基礎(chǔ)知識(shí)點(diǎn) 1.面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-oriented Programming OOP),UML(Unitied Modelling Language 統(tǒng)一建模語言)。將對(duì)象想像成“服務(wù)提供者”,它們看起來像什么?能夠提供哪 些服務(wù)?需要哪些對(duì)象? 2.Java中動(dòng)態(tài)綁定是默認(rèn)行為。Java采用動(dòng)態(tài)內(nèi)存分配方式,通過new操作在堆(Heap)的內(nèi) 存池中動(dòng)態(tài)創(chuàng)建對(duì)象。Java存儲(chǔ)結(jié)構(gòu)類型:1)寄存器2)堆棧,主要存儲(chǔ)對(duì)象引用3)堆,主要用于存放所有的Java對(duì)象4)常量存儲(chǔ),也就是程序代碼區(qū)5)非RAM存儲(chǔ),如流對(duì)象 和持久化對(duì)象?;绢愋筒挥胣ew來創(chuàng)建變量,而且這個(gè)變量直接存儲(chǔ)”值”,并置于堆棧中。3.BigInteger和BigDecimal的使用。當(dāng)變量作為類的成員使用時(shí) 當(dāng)變量作為類的成員使用時(shí),Java才確保給定其默認(rèn)初 當(dāng)變量作為類的成員使用時(shí) 始值,但是在方法中定義的變量,它有可能是任意值。面向?qū)ο蟮某绦蛟O(shè)計(jì)可以歸納為“向 對(duì)象發(fā)送消息”。關(guān)鍵字Static。4.Javadoc只能為public和protected成員進(jìn)行文檔注釋,但是也可以通過-private進(jìn)行標(biāo)記注 釋。Javadoc常用方法: @see 引用其他類,link package.class#member label},{@ {@docRoot},{@inheritDoc},@version,@ author,@since,@param,@return,@throws,@deprecated。5.整數(shù)除法會(huì)直接去掉結(jié)果的小數(shù)位?;绢愋偷膶?duì)象如果直接對(duì)它們賦值,對(duì)象指向同 一個(gè)常量存儲(chǔ)區(qū),但是如果通過對(duì)象來初始化則會(huì)指向不同的堆的存儲(chǔ)區(qū)。如: String st1 = new String(“A”);String st2 = new String(“A”);st1==st2 false String st1 = “A”;String st2 = “A”;st1==st2 true 6.邏輯操作符:與(&&)、或(||)、非(!),其中與(&&)、或(||)會(huì)產(chǎn)生短路現(xiàn)象。& |也支持邏輯 也支持邏輯 運(yùn)算操作。運(yùn)算操作 7.直接常量中L代表Long,F(xiàn)代表Float,D代表Double。顯示二進(jìn)制形式的話,可以通過Integer 和Long類的靜態(tài)方法toBinaryString()。如:Long.toBinaryString(10L)。 8.在返回void的方法中沒有return語句,那么在該方法的結(jié)尾處會(huì)有一個(gè)隱式的return。 一 般情況下每個(gè)方法都會(huì)有一個(gè)顯示的return語句。9.Break用于強(qiáng)行退出循環(huán),不執(zhí)行循環(huán)中剩余的語句,而continue則停止執(zhí)行當(dāng)前的迭代,然后退回循環(huán)起始處,開始下一次迭代。goto仍是Java的一個(gè)保留字,但在語言中并未使用它。Break和continue與標(biāo)簽一起使用,可以中斷循環(huán),直到標(biāo)簽所在的地方。This用法: public class Leaf { int I = 0;Leaf increment(){ i++;return this;} } 10.回答一個(gè)新技術(shù)的問題大概思路和步驟是:我們想干什么,怎么干,干的過程中遇到了 什么問題,現(xiàn)在用什么方式來解決。答題時(shí),先答是什么,再答有什么作用和要注意什么(這 部分最重要,展現(xiàn)自己的心得)。11.finalize的使用:垃圾回收只與內(nèi)存有關(guān),當(dāng)“垃圾回收”時(shí),finalize()得到調(diào)用。Java中 的對(duì)象都能被垃圾回收器回收,但是在“本地方法”的情況下,有可能在分配內(nèi)存時(shí)采用類 似C語言的做法通過malloc()函數(shù)來分配存儲(chǔ)空間時(shí),這時(shí)只能通過free()函數(shù)來釋放空間,而這些釋放操作必須要放到finalize()方法中,垃圾回收器才能正確的釋放內(nèi)存?!袄厥铡?都不保證一定會(huì)發(fā)生。 12.垃圾回收原理:引用記數(shù) 引用記數(shù)是一種簡單但速度很慢的垃圾回收技術(shù)。每個(gè)對(duì)象都含有一個(gè) 引用記數(shù) Java 編程思想第四版 讀書筆記 引用記數(shù)器,當(dāng)有引用連接至對(duì)象時(shí),引用計(jì)數(shù)加1。當(dāng)引用離開作用域或被置為null時(shí),引用計(jì)數(shù)減1。垃圾回收器會(huì)在含有全部對(duì)象的列表上遍歷,當(dāng)發(fā)現(xiàn)某個(gè)對(duì)象的引用計(jì)數(shù)為0 時(shí),就立即釋放其占用的空間。定位交互自引用的對(duì)象組所需的工作量極大,所以并沒有被 應(yīng)用于任何一種Java虛擬機(jī)中。Java虛擬機(jī)采用一種自適應(yīng) 自適應(yīng)的垃圾 回收技術(shù),Java虛擬機(jī)會(huì) 自適應(yīng) 進(jìn)行監(jiān)視,如果所有對(duì)象都很穩(wěn)定,垃圾回收器的效率降低的話,就切換到“標(biāo)記-清掃” 方式;同樣,Java虛擬機(jī)會(huì)跟蹤“標(biāo)記-清掃”的效果,要是堆空間出現(xiàn)很多碎片,就會(huì)切 換回“停止-復(fù)制”方式。“停止-復(fù)制”,先暫停程序的運(yùn)行,然后將所有存活 存活的對(duì)象從當(dāng)前 存活 堆復(fù)制到另一個(gè)堆,沒有被復(fù)制的全部都是垃圾?!皹?biāo)記-清掃”,從堆棧和靜態(tài)存儲(chǔ)區(qū)出發(fā),遍歷所有的引用,進(jìn)而找出所有存活的對(duì)象,每當(dāng)它找到一個(gè)存活對(duì)象,就會(huì)給對(duì)象設(shè)一個(gè) 標(biāo)記,這個(gè)過程中不會(huì)回收任何對(duì)象,只有全部標(biāo)記工作完成的時(shí)候,清理動(dòng)作才會(huì)開始。在清理過程中,沒有標(biāo)記的對(duì)象將被釋放,不會(huì)發(fā)生下任何復(fù)制動(dòng)作。13.初始化順序:先靜態(tài)對(duì)象,后“非靜態(tài)”對(duì)象,先變量,再構(gòu)造函數(shù),然后是方法。靜態(tài) 初始化只有在必要時(shí)刻才會(huì)進(jìn)行,如果不引用其對(duì)象,那么該對(duì)象中的靜態(tài)成員將不會(huì)被創(chuàng) 建,而且它們只會(huì)在第一次被訪問時(shí)進(jìn)行初始化,其后不會(huì)再次被初始化。14.對(duì)象的創(chuàng)建過程:1)當(dāng)首次創(chuàng)建對(duì)象時(shí),或類的靜態(tài)方法/靜態(tài)域首次被訪問時(shí),Java 解釋器必須查找類路徑,以定位.class文件。2)載入.class,有關(guān)靜態(tài)初始化的所有動(dòng)作都會(huì) 執(zhí)行。3)當(dāng)用new 創(chuàng)建對(duì)象時(shí),在堆上為對(duì)象分配存儲(chǔ)空間,而且這塊存儲(chǔ)空間會(huì)被清零,也就是說它會(huì)自動(dòng)地將對(duì)象中的所有基本類型數(shù)據(jù)都設(shè)置成默認(rèn)值,而引用是被設(shè)置成 null。4)執(zhí)行所有出現(xiàn)于字段定義處的初始化動(dòng)作。5)執(zhí)行構(gòu)造器。15.數(shù)組:java.util.Arrays常用方法的使用。binarySearch(),copyOf(),asList(),copyOfRange(),equals(),fill(),sort(),toString(),hashCode()。可變 參數(shù)列表:void f(float i,Character? args)。枚舉類型:enum,它可以在switch語句內(nèi)使用。16.類的結(jié)構(gòu)依次為:1)包的注釋2)package的設(shè)置3)import導(dǎo)入設(shè)置4)類的注釋5)類的編 寫。17.Java的訪問權(quán)限:類的訪問權(quán)限只有public和默認(rèn)包訪問權(quán)限,成員和方法有 public,protected,默認(rèn)包訪問權(quán)限和private。使用類的客戶端程序是無法訪問包訪問權(quán)限成員 的。包訪問權(quán)限的類的對(duì)象可以由包內(nèi)任何其他類來創(chuàng)建和使用,但是包外則不行。18.為了繼承,一般的規(guī)則是將所有的數(shù)據(jù)成員都指定為private,將所有的方法指定為public 或protected。Java會(huì)自動(dòng)在導(dǎo)出類的構(gòu)造器中插入對(duì)基類構(gòu)造器的調(diào)用。調(diào)用基類的構(gòu)造器 必須是你在導(dǎo)出類構(gòu)造器中要做的第一件事。19.代理,它是繼承與組合之間的中庸之道,因?yàn)槲覀儗⒁粋€(gè)成員對(duì)象置于所要構(gòu)造的類中(就像組合),但與此同時(shí)我們?cè)谛骂愔斜┞读嗽摮蓡T對(duì)象的所有方法(就像繼承)。20.清理方法的順序:首先,執(zhí)行類的所有特定的清理動(dòng)作,其順序同生成順序相反;然后,調(diào)用基類的清理方法。除了內(nèi)存之外,不能依賴?yán)厥掌魅プ鋈魏问?,如果需要進(jìn)行清理,最好是編寫自己的清理方法,但不要使用finalize()。@Override注解可以防止在你不想重載 時(shí)而意外地進(jìn)行了重載。21.組合與繼承之間的選擇:組合技術(shù)通常用于想在新類中使用現(xiàn)有類的功能而非它的接口,也就是在新類的嵌入某個(gè)對(duì)象,讓其實(shí)現(xiàn)所需要的功能,但新類的用戶看到的只是為新類所 定義的接口,而非所嵌入對(duì)象的接口,一般情況下會(huì)在新類中嵌入一個(gè)現(xiàn)有類的private對(duì)象。而繼承,它是指使用某個(gè)現(xiàn)有類,并開發(fā)一個(gè)它的特殊版本?!癷s-a”(是一個(gè))的關(guān)系是用 繼承來表達(dá)的,而“has-a”(有一個(gè))的關(guān)系則是用組合來表達(dá)的。22.final的用法:根據(jù)慣例,既是static又是final的域?qū)⒂么髮懕硎?,并使用下劃線分隔各個(gè)單 詞。類中所有的private方法都隱式的指定為是final的。final類中所有的方法都隱式指定為是 final的。當(dāng)前用HashMap替代了Hashtable,用ArrayList替代了Vector。 Java 編程思想第四版 讀書筆記 23.Java中除了static方法和final方法(private方法屬于final方法)之外,其他所有的方法都是 后期綁定。接口中的屬性都是public static final的,方法都是public 24.多態(tài):只有普通的方法調(diào)用可以是多態(tài)的。任何域訪問操作都將由編譯器解析,因此不 是多態(tài)的。如果某個(gè)方法是靜態(tài)的,它的行為也不具有多態(tài)性。25.初始化的實(shí)際過程:1)在其他任 何事物發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始化成二 進(jìn)制的零。2)如前所述那樣調(diào)用基類構(gòu)造器,此時(shí),調(diào)用被覆蓋后的方法(要在調(diào)用子類 構(gòu)造器之前調(diào)用)。3)按照聲明的順序調(diào)用成員的初始化方法。4)調(diào)用導(dǎo)出類的構(gòu)造器主 體。編寫構(gòu)造器時(shí)有一條有效的準(zhǔn)則: “用盡可能簡單的方法使對(duì)象進(jìn)入正常狀態(tài);如果可 以的話,避免調(diào)用其他方法”。在構(gòu)造器內(nèi)唯一能夠安全調(diào)用的那些方法是基類中的final方 法(也適用于private方法,它們自動(dòng)屬于final方法)。這些方法不能被覆蓋。26.一條通用的準(zhǔn)則是: “用繼承表達(dá)行為間的差異,并用字段表達(dá)狀態(tài)上的變化”。27.一個(gè)內(nèi)部類的對(duì)象能訪問其外圍對(duì)象的所有成員,還擁有其外圍類的所有元素的訪問權(quán)。在內(nèi)部類中,如果你需要生成對(duì)外部類對(duì)象的引用,可以使用外部類的名字后面緊跟圓點(diǎn)和 this,(OuterClass out = OuterClass.this)。有時(shí)你可能想要告知某些其他對(duì)象,去創(chuàng)建其某個(gè) 內(nèi)部類的對(duì)象,可以在new表達(dá)式中提供對(duì)其他外部類對(duì)象的引用,需要使用.new語法(OuterClass out = new OuterClass, OuterClass.InnerClass inner = out.new InnerClass())。在擁 有外部類對(duì)象之前是不可能創(chuàng)建內(nèi)部類對(duì)象的,但是,嵌套類(靜態(tài)內(nèi)部類)除外。如果定 義一個(gè)匿名內(nèi)部類,并希望它使用一個(gè)在其外部定義的對(duì)象,那么其參數(shù)引用必須是final 的。匿名類的實(shí)例初始化的實(shí)際效果就是構(gòu)造器,而且你不能重載實(shí)例初始化方法,它可以 擴(kuò)展類,也可以實(shí)現(xiàn)接口,但是實(shí)現(xiàn)接口,也只能實(shí)現(xiàn)一個(gè)接口。28.嵌套類(靜態(tài)內(nèi)部類):1)要?jiǎng)?chuàng)建嵌套類的對(duì)象,并不需要其外圍類的對(duì)象;2)不能從嵌 套類的對(duì)象中訪問非靜態(tài)的外圍類對(duì)象。30.為什么需要內(nèi)部類:1)每個(gè)內(nèi)部類都能獨(dú)立繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無論外圍 類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒有影響。2)內(nèi)部類可以更好的實(shí) 現(xiàn)“多重繼承”。3)內(nèi)部類可以有多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其外圍 類對(duì)象的信息相互獨(dú)立。4)在單個(gè)外圍類中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一個(gè) 接口或繼承同一個(gè)類。5)創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻并不依賴于外圍類對(duì)象的創(chuàng)建。 6)內(nèi)部類 并沒有令人迷惑的“is-a”關(guān)系,它是一個(gè)獨(dú)立的實(shí)體。31.閉包:它是一個(gè)可調(diào)用的對(duì)象,它記錄了一些信息,這些信息來自于創(chuàng)建它的作用域。通過內(nèi)部類提供閉包的功能是優(yōu)良的解決方案。使用局部內(nèi)部類而不使用匿名內(nèi)部類的的理 由是需要不止一個(gè)該內(nèi)部類的對(duì)象,或者需要一個(gè)已命名的構(gòu)造器。32.內(nèi)部類的繼承:內(nèi)部類的構(gòu)造器必須連接到指向其外圍類對(duì)象的引用,必須在構(gòu)造器內(nèi) 使用如下語法:enclosingClassReference.super();33.容器:List、Set、Query、Map。程序中不應(yīng)該使用過時(shí)的Vector,Hashtable和Stack。常用的類有:Collection,Collections,Arrays,ArrayList,LinkedList,HashSet,TreeSet,LinkedHashSet, HashMap,TreeMap,LinkedHashMap,Query,Stack,PriorityQuery 迭代器:Iteratror,ListIterator3 Java 編程思想第四版 讀書筆記 34.異常:把當(dāng)前異常對(duì)象重新拋出時(shí),printStackTrace()方法顯示原來異常拋出點(diǎn)的調(diào)用棧 信息,要想更新這個(gè)信息,可以調(diào)用fillInStackTrace()方法。如: throw(Exception)e.fillInStackTrace()。35.異常鏈:在捕獲一個(gè)異常后拋出另一個(gè)異常,而且希望把原始異常的信息保存下來?,F(xiàn) 在所有的Throwable的子類在構(gòu)造器中都可以接受一個(gè)cause(因由)對(duì)象作為參數(shù)。這個(gè)cause 就用來表示原始異常,這樣通過把原始異常傳遞給新的異常,使得即使在當(dāng)前位置創(chuàng)建并拋 出了新的異常,也能通過這個(gè)異常鏈追蹤到異常最初發(fā)生的位置。只有三種基本異常類(Error、Exception、RuntimeException)提供了帶cause參數(shù)的構(gòu)造器,其他的異常只能使用 initCause()方法。36.當(dāng)覆蓋方法的時(shí)候,只能拋出在基類方法的異常說明里列出的那些異常,或者拋出的異 常的子類或者不拋出異常。37.Java標(biāo)準(zhǔn)異常: Throwable這個(gè)Java類被用來表示任何可以作為異常被拋出的類。Throwable 對(duì)象可分為兩種類型(指從Throwable繼承而得到的類型):Error用來表示編譯時(shí)和系統(tǒng)錯(cuò)誤(除 特殊情況外,一般不用你關(guān)心);Exception是可以被拋出的基本類型,在Java類庫、用 戶方法以及運(yùn)行時(shí)故障中都可能拋出Exception型異常。所以Java程序員關(guān)心的基類型通常是 Exception。38.RuntimeException:Java運(yùn)行時(shí)異常,它屬于Java的標(biāo)準(zhǔn)運(yùn)行時(shí)檢測的一部分,它會(huì)自動(dòng)被 Java虛擬機(jī)拋出,它也被稱為“不受檢查異?!保@種異常屬于錯(cuò)誤,將被自動(dòng)捕獲,不用 自己進(jìn)行處理。除此之外的異常需要進(jìn)行聲明,并進(jìn)行捕獲或都向上拋出。只能在代碼中忽 略RuntimeException(及其子類)類型的異常,其他類型異常的處理都是由編譯器強(qiáng)制實(shí)施 的。RuntimeException代表的編程錯(cuò)誤:1)無法預(yù)料的錯(cuò)誤;2)作為程序同,應(yīng)該在代碼 中進(jìn)行檢查的錯(cuò)誤。39.catch會(huì)捕獲基類異常本身以及所有從它派生的異常,如果將基類異常放在前面,子類異 常放在后面的話,子類異常永遠(yuǎn)不會(huì)被捕獲,編輯器會(huì)報(bào)錯(cuò)。Unreachable catch block for RuntimeException.It is already handled by the catch block for Exception。 40.異常處理的一個(gè)重要目標(biāo)就是把錯(cuò)誤處理的代碼同錯(cuò)誤發(fā)生的地點(diǎn)分離。應(yīng)該在下列情 況下使用異常:1)在恰當(dāng)?shù)募?jí)別處理問題。(在知道該如何處理的情況下捕獲異常) 2)解 決問題并且重新調(diào)用產(chǎn)生異常的方法。3)進(jìn)行少許修被,然后繞過異常發(fā)生的地方繼續(xù)執(zhí) Java 編程思想第四版 讀書筆記 行。4)用別的數(shù)據(jù)進(jìn)行計(jì)算,以代替方法預(yù)計(jì)會(huì)返回的值。5)把當(dāng)前運(yùn)行環(huán)境下能做的事 情盡量做完,然后把相同的異常重拋到更高層。6)把當(dāng)前運(yùn)行環(huán)境下能做的事情盡量做完,然后把不同的異常拋到更高層。7)終止程序。8)進(jìn)行簡化。9)讓類庫和程序更安全。41.字符器:String,StringBuilder,Formatter.格式化語法: %[argument_index$][flags][width][.precision]conversion 在默認(rèn)的情況下,數(shù)據(jù)是右對(duì)齊,不過可以通過使用“-”標(biāo)志來改變對(duì)齊方向。42.正則表達(dá)式:意思是“我要插入一個(gè)正則表達(dá)式的反斜線,所以其后的字符具有特殊的 意義”。數(shù)字的正則表達(dá)式是:d,普通反斜線:,換行:n,制表符:t。要表示“一個(gè) 或多個(gè)之前的表達(dá)式”,使用+?!傲銈€(gè)或多個(gè)”,使用?。(-|+)?:+在正則表達(dá)式中有特殊意 義,必須使用將其轉(zhuǎn)義。String類有matches()和split()方法處理正則表達(dá)式。43.我們通過java.util.regex.Pattern類和Matcher類來構(gòu)造正則表達(dá)式對(duì)象。導(dǎo)入java.util.regex 包,用static Pattern.compile()方法來編譯正則表達(dá)式生成一個(gè)Pattern對(duì)象,再將你想要檢索 的字符串傳入Pattern對(duì)象的matcher()方法,它會(huì)生成一個(gè)Matcher對(duì)象,最后通過操作Matcher 對(duì)象來實(shí)現(xiàn)相關(guān)功能。還可以通過Scanner來完成正則表達(dá)式相關(guān)功能。44.在Java中,所有的類型轉(zhuǎn)換都是在運(yùn)行進(jìn)進(jìn)行正確性檢查的。通過Class.forName()獲得 Class對(duì)象的引用,也可以通過Object類的getClass()方法來獲得。45.使用類的準(zhǔn)備工作:1)加載,這是由類加載器執(zhí)行,該步驟將查找字節(jié)碼,并從這些字 節(jié)碼中創(chuàng)建一個(gè)Class對(duì)象。2)鏈接,將驗(yàn)證類中的字節(jié)碼,為靜態(tài)域分配存儲(chǔ)空間,并且 如果必需的話,將解析這個(gè)類創(chuàng)建的對(duì)其他類的所有引用。3)初始化,如果該類具有超類,則對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊。(構(gòu)造器隱式地是靜態(tài)的)。46.RTTI和反射之間的區(qū)別:對(duì)RTTI來說,編譯器在編譯時(shí)打開和檢查.class文件。而對(duì)于反 射機(jī)制來說,.class文件在編譯時(shí)是不可獲取的,所以是在運(yùn)行時(shí)打開和檢查.class文件。47.泛型中T代表類型Class,要顯式地指明類型,必須在點(diǎn)操作符與方法名之間插入尖括號(hào),然后把類型置于尖括號(hào)中;如果是在定義該方法的類的內(nèi)部,必須在點(diǎn)操作符之前使用this 關(guān)鍵字,如果是使用static的方法,必須在點(diǎn)操作符之前加上類名。在泛型代碼內(nèi)部,無法 獲得任何有關(guān)泛型參數(shù)類型的信息。在泛型中創(chuàng)建數(shù)組,推薦使用Array.newInstance()。泛 型( SuperClass> 48.任何基本類型都不能作為類型參數(shù),但是可以使用它們的包裝類,如不能使用 ArrayList,但可以使用ArrayList 49.異常的分類:1)Error:稱為錯(cuò)誤,由Java虛擬機(jī)生成并拋出,包括動(dòng)態(tài)鏈接失敗、虛擬 機(jī)錯(cuò)誤等,程序?qū)ζ洳蛔鎏幚恚?)Exception:所有異常類的父類,其子類對(duì)應(yīng)了各種各樣可 能出現(xiàn)的異常事件,一般需要用戶顯示的聲明或捕獲; 3)Runtime Exception:一類特殊的異常,如被0除、數(shù)據(jù)下標(biāo)超范圍等,其產(chǎn)生比較頻繁,處理麻煩,如果顯式的聲明或捕獲將會(huì)對(duì) 程序可讀性和運(yùn)行效率影響很大。因此由系統(tǒng)自動(dòng)檢測并將它們交給缺省的異常處理程序(用戶可不必對(duì)其處理)。50.使用自定義異常一般步驟:1)通過繼承java.lang.Exception類聲明自己的異常類;2)在 方法適當(dāng)?shù)奈恢蒙勺远x異常的實(shí)例,并用throw語句拋出; 在方法的聲明部分用throws 3)語句聲明該方法可能拋出的異常。 二 專項(xiàng)復(fù)習(xí) 1.容器 2.正則表達(dá)式 Java 編程思想第四版 讀書筆記 3.設(shè)計(jì)模式 4.異常 5.泛型 6.反射 7.多線程 8.IO 常用包(加粗是抽象類,斜體是接口,普通是類)三 J2SE 常用包(加粗是抽象類,斜體是接口,普通是類) 1.java.lang 提供利用 Java 編程語言進(jìn)行程序設(shè)計(jì)的基礎(chǔ)類。Process、ProcessBuilder、Runtime、System、String、Object、Class、ClassLoader、Math、Compiler、Thread、ThreadGroup、Runnable、ThreadLocal、InheritableThreadLocal、Package 2.java.util ArrayList、Arrays、Collection、Collections、LinkedList、HashSet、TreeSet、Iterator、ListIterator、Map、HashMap、TreeMap、Comparator 歷史遺留的類:Dictionary、Hashtable、Properties、Stack、Vector、Enumeration 使用迭代函數(shù)的步驟:1)通過調(diào)用類集的iterator()或listIterator()方法獲得對(duì)類集頭的迭代函 數(shù);2)建立一個(gè)調(diào)用hasNext()方法的循環(huán),只要hasNext()返回true,就進(jìn)行循環(huán)迭代;3)在循環(huán)內(nèi)部,通過調(diào)用next()方法來得到每一個(gè)元素。GregorianCalendar、TimeZone、SimpleTimeZone、Locale、DateFormat、BitSet、Calendar、SimpleDateFormat、Random、Observer、Observable、Timer、TimerTask GregorianCalendar定義了兩個(gè)域:AD和BC。它們代表由公歷定義的兩個(gè)紀(jì)元。BC公元前,AD公元后 3.java.io InputStream、OutputStream Reader、Writer OutputStream、Reader Writer、FileInputStream、FileOutputStream、InputStream OutputStream Reader Writer ByteArrayInputStream、ByteArrayOutputStream、FilterOutputStream、FilterInputStream、BufferedInputStream、BufferedOutputStream、SequenceInputStream、PrintStream、RandomAccessFile FileReader、FileWriter、CharArrayReader、CharArrayWriter、BufferedReader、BufferedWriter、PrintWriter ObjectInputStream、ObjectOutputStream序列化的類必須實(shí)現(xiàn)java.io.Serializable 或 java.io.Externalizable 接口的對(duì)象才能從流讀取。4.java.net InetAddress、URL、URLConnection Java中有兩類TCP套接字。一種是服務(wù)器端的,另一種是客戶端的。ServerSocket類設(shè) 計(jì)成在等待客戶建立連接之前不做任何事的“監(jiān)聽器”。Socket類為建立連向服務(wù)器套接 字以及啟動(dòng)協(xié)議交換而設(shè)計(jì)?;?index.htm 文件。所以,http:/// 與http:///index.htm 是相同 的。Java通過兩個(gè)類實(shí)現(xiàn)UDP協(xié)議頂層的數(shù)據(jù)報(bào):DatagramPacket對(duì)象是數(shù)據(jù)容器,DatagramSocket是用來發(fā)送和接受DatagramPackets的機(jī)制。5.java.rmi第五篇:Java編程思想第四版_讀書筆記