面向?qū)ο螅ㄏ拢?/h1>
本章思維導(dǎo)圖
4-0面向?qū)ο螅ㄏ拢?png
包裝類(Wrapper Class)

解決8種基本數(shù)據(jù)類型當(dāng)成Object類型變量使用
基本數(shù)據(jù)類型的包裝類
-
byte==Byte -
short==Short -
int==Integer -
long==Long -
char==Character -
float==Float -
double==Double -
boolean==Boolean
JKD1.5提供了自動(dòng)裝箱(Autoboxing)和自動(dòng)拆箱(AutoUnboxing)
- 自動(dòng)裝箱是把一個(gè)基本數(shù)據(jù)類型變量直接賦給對(duì)應(yīng)的包裝類變量或者賦給
Object變量 - 自動(dòng)拆箱是直接把包裝類對(duì)象直接賦給一個(gè)對(duì)應(yīng)的基本類型變量
包裝類可實(shí)現(xiàn)基本類型變量和字符串之間的轉(zhuǎn)換
- 把字符串類型的值轉(zhuǎn)換為基本類型的值
-
parseXxx(String s)靜態(tài)方法,除Character之外所有包裝類都提供了該方法 -
valueOf(String s)靜態(tài)方法
-
包裝類的引用類型變量可以直接和基本數(shù)據(jù)類型作比較
- 但是
Integer包裝類直接把-128~127之間的整數(shù)放入cache數(shù)組中緩存起來(lái) - 包裝類提供了一個(gè)靜態(tài)
compare(xxx var1, xxx var2)方法,來(lái)比較兩個(gè)基本類型值的大小
包裝類無(wú)符號(hào)運(yùn)算的方法
Integer、Long
static String toUnsignedString(int/long i)
- 指定int或long型整數(shù)轉(zhuǎn)換為無(wú)符號(hào)整數(shù)對(duì)應(yīng)的字符串
static String toUsignedString(int\long i, int radix)
- 指定int或long型整數(shù)轉(zhuǎn)換為指定進(jìn)制的無(wú)符號(hào)整數(shù)對(duì)應(yīng)的字符串
static xxx parseUnsignedXxx(String s)
- 指定字符串解析成無(wú)符號(hào)整數(shù)
static xxx parseUnsignedXxx(String s, int radix)
- 指定字符串按指定進(jìn)制解析成無(wú)符號(hào)整數(shù)
static int compareUnsigned(xxx x, xxx y)
- 將x、y兩個(gè)整數(shù)轉(zhuǎn)換為無(wú)符號(hào)整數(shù)后比較大小
Byte、Short
toUnsignedInt(xxx x)
toUnsignedLong(xxx x)
- 無(wú)符號(hào)類就是把二進(jìn)制代碼的最高位的符號(hào)位當(dāng)成數(shù)值類處理
處理對(duì)象
打印對(duì)象和toString方法
- 直接打印對(duì)象名是
類名+@+hashCode -
toString()方法是Object類的一個(gè)實(shí)例方法- 是一個(gè)特殊的方法,是一個(gè)“自我描述”的方法
- 重寫(xiě)類的
toString()方法,可對(duì)類介紹 類名[field1=值1, field2=值2, ...]
==和equals方法
- 對(duì)于兩個(gè)引用類型變量,只有都指向同一個(gè)對(duì)象時(shí),
==才會(huì)返回true-
==不可用于比較類型上沒(méi)有父子關(guān)系的兩個(gè)對(duì)象 -
"hello"直接量和new String("hello")的區(qū)別- 使用形如
"hello"的字符串直接量,JVM將會(huì)使用常量池來(lái)管理這些字符串 - 使用
new String("hello")時(shí),JVM會(huì)先使用常量池來(lái)管理"hello"直接量,在調(diào)用String類的構(gòu)造器來(lái)創(chuàng)建一個(gè)新的String對(duì)象,新創(chuàng)建的String對(duì)象被保存在堆內(nèi)存中 -
new String("hello")一共產(chǎn)生了兩個(gè)字符串對(duì)象 - 常量池(constant pool)專門(mén)用戶管理在編譯時(shí)被確定并被保存在已編譯的.class文件中的一些數(shù)據(jù)。它包括了關(guān)于類、方法、接口中的常量,還包括字符串常量
- 常量池保住相同的字符串直接量只有一個(gè)
- 使用形如
-
-
equals()方法-
equals()方法是Object類提供的一個(gè)實(shí)例方法- 重寫(xiě)
equals()方法來(lái)實(shí)現(xiàn)自定義的相等標(biāo)準(zhǔn)
- 重寫(xiě)
- String的
equals()方法用來(lái)判斷兩個(gè)字符串是否相等 -
實(shí)例名.getCall()和類名.class - 正確重寫(xiě)
euqls()方法應(yīng)該滿足的條件- 自反性:對(duì)任意x,x.equals(x)一定返回true
- 對(duì)稱性:對(duì)任意x和y,如果y.equals(x)返回true,則x.equals(y)也返回true
- 傳遞性:對(duì)任意x、y、z,如果x.equals(y)返回true,y.equals(z)返回true,則x.equals(z)一定返回true
- 對(duì)任何不是null的x,x.equals(null)一定返回false
-
類成員
static關(guān)鍵字修飾的成員就是類成員
static可以修飾成員變量、方法、初始化塊、內(nèi)部類(接口、枚舉)
不允許類成員訪問(wèn)實(shí)例成員
單例(Singleton)類
- 一個(gè)類始終只能創(chuàng)建一個(gè)實(shí)例
- 把類構(gòu)造器使用
private修飾,提供一個(gè)public方法作為該類的訪問(wèn)點(diǎn),用于創(chuàng)建該類的對(duì)象,且該方法必須使用static修飾 - 該類還必須緩存已經(jīng)創(chuàng)建過(guò)的對(duì)象,用來(lái)判斷該類是否曾經(jīng)創(chuàng)建過(guò)對(duì)象
final修飾符
final關(guān)鍵字可用于修飾類、變量、方法,用于表示不可改變
final成員變量
- 必須由程序員顯式地指定初始值
- 類變量
- 必須在靜態(tài)初始化塊中指定初始值或聲明該類變量時(shí)指定初始值
- 實(shí)例變量
- 必須在非靜態(tài)初始化塊、聲明該實(shí)例變量或構(gòu)造器中指定初始值
- 在顯式初始化之前不能訪問(wèn),但可以通過(guò)方法來(lái)訪問(wèn)(java的一個(gè)缺陷)
final局部變量
final修飾的形參,不允許在方法內(nèi)被賦值
可執(zhí)行“宏替換”的final變量
- 只要滿足3個(gè)條件,
final變量就不再是一個(gè)變量,而是相當(dāng)于一個(gè)直接量- 使用
final修飾 - 在定義時(shí)制定了初始值
- 該初始值可以在編譯時(shí)確定下來(lái)
- 使用
final方法
-
final修飾的方法不可被重寫(xiě) - 子類可重寫(xiě)
private final修飾的方法- 因?yàn)?code>private修飾的方法,子類無(wú)法訪問(wèn),如果子類定義了相同方法名、相同形參列表、相同返回值類型的方法,只是重新定義了一個(gè)新方法
final類
-
final修飾的類不可以有子類
不可變(immutable)類
創(chuàng)建類的實(shí)例后,該實(shí)例的實(shí)例變量不可改變
- 規(guī)則
- 使用private和final修飾該類的成員變量
- 提供帶參數(shù)的構(gòu)造器,用于根據(jù)傳入?yún)?shù)來(lái)初始化類里的成員變量
- 僅為類的成員變量提供getter方法,不提供setter方法
- 注意引用類型的成員變量
抽象類
- 有抽象方法的類只能定義成抽象類
- 抽象類里可以沒(méi)有抽象方法
規(guī)則
- 抽象類必須使用
abstract來(lái)修飾,抽象方法也必須使用abstract來(lái)修飾,抽象方法不能有方法體 - 抽象類不能被實(shí)例化
- 抽象類可以包含成員變量、方法(普通方法、抽象方法)、構(gòu)造器、初始化塊、內(nèi)部類(接口、枚舉)
- 抽象類的構(gòu)造器不能用于創(chuàng)建實(shí)例,主要是用于被其子類調(diào)用
- 含有抽象方法的類(直接定義了一個(gè)抽象方法、繼承了一個(gè)抽象父類,但沒(méi)有完全實(shí)現(xiàn)父類包含的抽象方法、實(shí)現(xiàn)了一個(gè)接口,但沒(méi)有完全實(shí)現(xiàn)接口包含的抽象方法)只能被定義成抽象類
abstract修飾類時(shí),表明這個(gè)類只能被繼承
abstract修飾方法時(shí),表明這個(gè)方法必須由子類提供實(shí)現(xiàn)(重寫(xiě))
final和abstract永遠(yuǎn)不能同時(shí)使用
接口
更特殊的抽象類,接口(interface)
[修飾符] interface 接口名 extends 父接口1,... {
零個(gè)到多個(gè)常量定義...
零個(gè)到多個(gè)抽象方法定義...
零個(gè)到多個(gè)內(nèi)部類、接口、枚舉定義...
零個(gè)到多個(gè)私有方法、默認(rèn)方法、類方法定義.
}
- 修飾符可以是
public或省略 - 一個(gè)接口可以由多個(gè)直接父接口,但接口只能繼承接口,不能繼承類
接口里不能包含構(gòu)造器和初始化塊定義
接口里可以包含成員變量,方法,內(nèi)部類,都只能是public訪問(wèn)權(quán)限,如果省略也是public
- 成員變量只能是靜態(tài)常量
- 方法只能是抽象實(shí)例方法、類方法、默認(rèn)方法、私有方法
- 內(nèi)部類包括內(nèi)部接口、枚舉
私有方法可以擁有方法體,可以使用static修飾
靜態(tài)常量,系統(tǒng)會(huì)自動(dòng)增加static和final修飾符
如果定義的不是默認(rèn)方法、類方法、私有方法,系統(tǒng)會(huì)自動(dòng)為普通方法增加abstract修飾符
- 普通方法不能有方法體
- 類方法、默認(rèn)方法、私有方法都必須由方法體
- 默認(rèn)方法需要用
default修飾 - 私有方法用
private修飾
接口的繼承
- 接口支持多繼承
- 子接口擴(kuò)展某個(gè)父接口,會(huì)獲得父接口里定義的所有抽象方法、常量
使用接口
- 接口不能用于創(chuàng)建實(shí)例,但可以用于聲明引用類型變量,這個(gè)引用類型變量必須引用到其實(shí)現(xiàn)類的對(duì)象
- 接口的用途
- 定義變量,可用于強(qiáng)制類型轉(zhuǎn)換
- 調(diào)用接口中定義的常量
- 被其他類實(shí)現(xiàn)
- 實(shí)現(xiàn)接口使用
implements關(guān)鍵字-
一個(gè)類可以實(shí)現(xiàn)多個(gè)接口
[修飾符] class 類名 implements 接口1,接口2... { // 類體部分 } 實(shí)現(xiàn)接口會(huì)獲得接口里定義的常量(成員變量)、方法(抽象方法、默認(rèn)方法)
-
如果類實(shí)現(xiàn)接口后沒(méi)有重寫(xiě)接口里的抽象方法,那就必須定義成抽象類
- 如果A類實(shí)現(xiàn)了B接口和C接口,那么A對(duì)象既可以直接賦給B變量,也可以直接賦給C變量
- 實(shí)現(xiàn)接口時(shí)必須使用
public訪問(wèn)控制符,因?yàn)榻涌诶锓椒ǘ际?code>public,而子類重寫(xiě)父類時(shí)訪問(wèn)權(quán)限只能更大或相等
-
接口和抽象類
相同特征
- 接口和抽象類都不能被實(shí)例化
- 接口和抽象類都快可以包含抽象方法
接口體現(xiàn)的是一種規(guī)范,類似于整個(gè)系統(tǒng)的“總綱”,一旦接口改變,將可能導(dǎo)致系統(tǒng)中大部分類需要改寫(xiě)
差別
- 接口里只能包含抽象方法、默認(rèn)方法、私有方法、類方法,不能為普通方法提供方法實(shí)現(xiàn);抽象類完全可以包含普通方法
- 接口里只能定義靜態(tài)常量,不能定義普通成員變量;抽象類里則都可以定義
- 接口里不包含構(gòu)造器;抽象類可以包含構(gòu)造器,但抽象類構(gòu)造器不是用于創(chuàng)建對(duì)象,而是讓其子類調(diào)用這些構(gòu)造器來(lái)完成屬于抽象類的初始化操作
- 接口里不能包含初始化塊;抽象類可以
- 一個(gè)類最多只能有一個(gè)直接父類,包括抽象類;但一個(gè)接口可以實(shí)現(xiàn)多個(gè)接口
內(nèi)部類
把一個(gè)類放在另一個(gè)類的內(nèi)部定義,定義在其他類內(nèi)部的類被稱為內(nèi)部類(嵌套類),包含內(nèi)部類的類被稱為外部類(宿主類)
作用
- 內(nèi)部類提供了更好的封裝,可以把內(nèi)部類隱藏在外部類之內(nèi),不允許同一個(gè)包中其他類訪問(wèn)該類
- 內(nèi)部類成員可以直接訪問(wèn)外部類的私有數(shù)據(jù),內(nèi)部類被當(dāng)成外部類成員,同一個(gè)類的成員之間可以互相訪問(wèn)
- 但外部類不能訪問(wèn)內(nèi)部類的實(shí)現(xiàn)細(xì)節(jié)
- 匿名內(nèi)部類適合用于創(chuàng)建那些僅需要一次使用的類
- 內(nèi)部類最多可使用三個(gè)修飾符:private、proteced、static
- 外部類不可以使用這三個(gè)修飾符
- 非靜態(tài)內(nèi)部類不能擁有靜態(tài)成員
非靜態(tài)內(nèi)部類
內(nèi)部類都被作為成員內(nèi)部類定義,而不是作為局部?jī)?nèi)部類
- 成員內(nèi)部類是一種與成員變量、方法、構(gòu)造器和初始化塊相似的類成員
- 局部?jī)?nèi)部類和匿名內(nèi)部類則不是類成員
成員內(nèi)部類
- 靜態(tài)內(nèi)部類
- 使用static修飾的成員內(nèi)部類
- 非靜態(tài)內(nèi)部類
- 沒(méi)有使用static修飾的成員內(nèi)部類
- 內(nèi)部類生成的class文件格式:
OuterClass$InnerClass.class - 非靜態(tài)內(nèi)部類里可以直接訪問(wèn)外部類的
private成員 - 在非靜態(tài)內(nèi)部類對(duì)象里,保存了一個(gè)它所寄生的外部類對(duì)象的引用
- 當(dāng)調(diào)用非靜態(tài)內(nèi)部類的實(shí)例方法時(shí),必須有一個(gè)非靜態(tài)內(nèi)部類實(shí)例,非靜態(tài)內(nèi)部類實(shí)例必須寄生在外部類實(shí)例里
- 非靜態(tài)內(nèi)部類的方法訪問(wèn)某個(gè)變量時(shí):
該方法的局部變量->內(nèi)部類成員變量->外部類成員變量- 如果外部類成員變量、內(nèi)部類成員變量、內(nèi)部類方法局部變量同名
- 使用
this、外部類類名.this區(qū)分
- 使用
- 非靜態(tài)內(nèi)部類的成員不能在外部類直接使用
- 需要在外部類顯示創(chuàng)建內(nèi)部類對(duì)象來(lái)調(diào)用訪問(wèn)實(shí)例成員
- 如果外部類成員變量、內(nèi)部類成員變量、內(nèi)部類方法局部變量同名
- 不允許在外部類的靜態(tài)成員中直接使用非靜態(tài)內(nèi)部類
- 不允許在非靜態(tài)內(nèi)部類定義靜態(tài)成員
靜態(tài)內(nèi)部類
使用static來(lái)修飾一個(gè)內(nèi)部類,這個(gè)內(nèi)部類就屬于外部類本身
- 靜態(tài)內(nèi)部類可以包含靜態(tài)成員,也可以包含非靜態(tài)成員
- 靜態(tài)內(nèi)部類不能訪問(wèn)外部類實(shí)例變量,只能訪問(wèn)外部類的類成員
- 內(nèi)部類的實(shí)例方法也不能訪問(wèn)外部類的實(shí)例成員,只能訪問(wèn)外部類的靜態(tài)成員
- 靜態(tài)內(nèi)部類時(shí)外部類的類相關(guān)的,靜態(tài)內(nèi)部類對(duì)象不是寄生在外部類的實(shí)訓(xùn)中,而是寄生在外部類的類本身中
- 外部類不能直接訪問(wèn)內(nèi)部類的成員,但可以使用靜態(tài)內(nèi)部類的類名作為調(diào)用者來(lái)訪問(wèn)靜態(tài)內(nèi)部類的類成員,也可以使用靜態(tài)內(nèi)部類對(duì)象作為調(diào)用者來(lái)訪問(wèn)靜態(tài)內(nèi)部類的實(shí)例成員
- 接口里可以定義內(nèi)部類
- 接口里定義內(nèi)部類默認(rèn)使用
public static修飾 - 接口內(nèi)部類只能是靜態(tài)內(nèi)部類
- 接口也可以定義內(nèi)部接口
- 內(nèi)部接口時(shí)接口的成員,系統(tǒng)默認(rèn)添加
public static修飾符- 意義不大
- 內(nèi)部接口時(shí)接口的成員,系統(tǒng)默認(rèn)添加
- 接口里定義內(nèi)部類默認(rèn)使用
使用內(nèi)部類
- 在外部類內(nèi)部使用內(nèi)部類
- 在外部類以外使用非靜態(tài)內(nèi)部類
- 若想在外部類以外的地方使用內(nèi)部類,內(nèi)部類不能使用
private訪問(wèn)控制權(quán)限-
private修飾的內(nèi)部類只能在外部類內(nèi)使用 - 省略訪問(wèn)控制符,內(nèi)部類只能在和外部類在同一包下的其它類使用
- 使用
protected修飾的內(nèi)部類,可被與外部類同一包下的其他類和外部類的子類使用 - 在外部類以外的地方定義內(nèi)部類(包括靜態(tài)和非靜態(tài)兩種)變量
OuterClass.InnerClass varName
-
- 非靜態(tài)內(nèi)部類的對(duì)象必須寄生在外部類的對(duì)象里,因此創(chuàng)建非靜態(tài)內(nèi)部類對(duì)象之前,必須先創(chuàng)建其外部類對(duì)象
- 若想在外部類以外的地方使用內(nèi)部類,內(nèi)部類不能使用
- 在外部類以外的地方創(chuàng)建非靜態(tài)內(nèi)部類實(shí)例
OuterInstance.new InnerConstructor()
- 在外部類以外使用靜態(tài)內(nèi)部類
- 靜態(tài)內(nèi)部類是外部類類相關(guān)的,創(chuàng)建靜態(tài)內(nèi)部類時(shí)無(wú)須創(chuàng)建外部類對(duì)象
new OuterClass.InnerConstructor()
- 創(chuàng)建靜態(tài)內(nèi)部類的子類
-
public class StaticSubClass extends StaticOut.StaticIn{}- 定義一個(gè)靜態(tài)內(nèi)部類時(shí),外部類像一個(gè)包
-
- 不管靜態(tài)內(nèi)部類還是非靜態(tài)內(nèi)部類,聲明變量的語(yǔ)法完全一樣,區(qū)別只是在創(chuàng)建內(nèi)部類對(duì)象時(shí)
- 靜態(tài)內(nèi)部類是外部類類相關(guān)的,創(chuàng)建靜態(tài)內(nèi)部類時(shí)無(wú)須創(chuàng)建外部類對(duì)象
局部?jī)?nèi)部類
- 把一個(gè)內(nèi)部類放在方法里定義
- 局部?jī)?nèi)部類僅在該方法里有效
- 局部?jī)?nèi)部類不能是使用訪問(wèn)控制符和
static修飾符- 不管是局部變量還是局部?jī)?nèi)部類,它們的上一級(jí)程序單元都是方法而不是類,都不能使用
static修飾
- 不管是局部變量還是局部?jī)?nèi)部類,它們的上一級(jí)程序單元都是方法而不是類,都不能使用
- 局部?jī)?nèi)部類的class文件命名格式:
OuterClass$NInnerClass.class - 局部?jī)?nèi)部類在實(shí)際開(kāi)發(fā)中很少使用
匿名局部?jī)?nèi)部類
創(chuàng)建只需要一次使用的類
-
創(chuàng)建匿名內(nèi)部類時(shí)會(huì)立即創(chuàng)建一個(gè)該類的實(shí)例,這個(gè)類定義立即消失,匿名內(nèi)部類不能重復(fù)使用
new 實(shí)現(xiàn)接口() | 父類構(gòu)造器(實(shí)參列表) { // 匿名內(nèi)部類的類體部分 } 匿名內(nèi)部類必須繼承一個(gè)父類或?qū)崿F(xiàn)一個(gè)接口,但最多只能繼承一個(gè)父類或?qū)崿F(xiàn)一個(gè)接口
-
規(guī)則
- 匿名內(nèi)部類不能是抽象類
- 匿名內(nèi)部類不能定義構(gòu)造器,但可以定義初始化塊
通過(guò)繼承父類來(lái)創(chuàng)建匿名內(nèi)部類時(shí),匿名內(nèi)部類將擁有和父類相似的構(gòu)造器,相似是指擁有相同形參列表
如果局部變量?jī)?nèi)匿名內(nèi)部類訪問(wèn),該局部變量相當(dāng)于自己使用了
final修飾
Lambda表達(dá)式
lambda表達(dá)式入門(mén)
支持將代碼塊作為方法參數(shù),允許使用更簡(jiǎn)潔的代碼來(lái)創(chuàng)建只有一個(gè)抽象方法的接口(這種接口成為函數(shù)式接口)的實(shí)例
代替匿名內(nèi)部類創(chuàng)建對(duì)象,lambda表達(dá)式的代碼塊將會(huì)代替實(shí)現(xiàn)抽象方法的方法體
-
相當(dāng)于一個(gè)匿名方法
(形參列表) -> { // 代碼塊 } -
組成
- 形參列表
- 允許省略形參類型;如果形參列表中只有一個(gè)參數(shù),形參列表的圓括號(hào)也可以省略
- 箭頭
-> - 代碼塊
- 如果代碼塊只有一條語(yǔ)句,允許省略代碼塊的花括號(hào);若只有一條return語(yǔ)句,return關(guān)鍵字也可以省略;
- 形參列表
lambda表達(dá)式會(huì)被當(dāng)成一個(gè)“任意類型”的對(duì)象
lambda表達(dá)式與函數(shù)式接口
- lambda表達(dá)的類型,也被稱為
目標(biāo)類型(target type) - lambda表達(dá)式的目標(biāo)類型必須是
函數(shù)式接口(functional interface)- 函數(shù)式接口代表只包含一個(gè)抽象方法的接口
- 函數(shù)式接口可以包含多個(gè)默認(rèn)方法、類方法,但只能聲明一個(gè)抽象方法
- lambda表達(dá)式的結(jié)果就是被當(dāng)成對(duì)象,因此程序中完全可以使用lambda表達(dá)式進(jìn)行賦值
- lambda表達(dá)式的限制
- lambda表達(dá)式的目標(biāo)類型必須是明確的函數(shù)式接口
- lambda表達(dá)式只能為函數(shù)式接口創(chuàng)建對(duì)象
- 常見(jiàn)方式
- 將lambda表達(dá)式賦值給函數(shù)式接口類型的變量
- 將lambda表達(dá)式作為函數(shù)式接口類型的參數(shù)傳給某個(gè)方法
- 使用函數(shù)式接口對(duì)lambda表達(dá)式進(jìn)行強(qiáng)制類型轉(zhuǎn)換
方法引用與構(gòu)造器引用
- 需要使用兩個(gè)英文冒號(hào)
- 引用類方法
類名::類方法- 函數(shù)式接口中被實(shí)現(xiàn)方法的全部參數(shù)傳給該類方法作為參數(shù)
(a, b, ...) -> 類名.類方法(a, b, ...)
- 引用特定對(duì)象的實(shí)例方法
特定對(duì)象::實(shí)例方法- 函數(shù)式接口中被實(shí)現(xiàn)方法的全部參數(shù)傳給該方法作為參數(shù)
(a, b, ...) -> 特定對(duì)象.實(shí)例方法(a, b, ...)
- 引用某類對(duì)象的實(shí)例方法
類名::實(shí)例方法- 函數(shù)式接口中被實(shí)現(xiàn)方法的第一個(gè)參數(shù)作為調(diào)用者,后面的參數(shù)全部傳給該方法作為參數(shù)
(a, b, ...) -> a.實(shí)例方法(b, ...)
- 引用構(gòu)造器
類名::new- 函數(shù)式接口中被實(shí)現(xiàn)方法的全部參數(shù)傳給該構(gòu)造器作為參數(shù)
(a, b, ...) -> new 類名(a, b, ...)
-
Java.util.function包下預(yù)定義了大量函數(shù)式接口-
XxxFunction:這類接口中通常包含一個(gè)apply()抽象方法, 該方法對(duì)參數(shù)進(jìn)行處理、轉(zhuǎn)換(apply()方法的處理邏輯由lambda表達(dá)式來(lái)實(shí)現(xiàn)),然后返回一個(gè)新的值。該函數(shù)式接口通常用于對(duì)指定數(shù)據(jù)進(jìn)行轉(zhuǎn)換處理 -
XxxConsumer:這類接口通常包含一個(gè)accept()抽象方法,該方法與XxxFunction接口中的apply()方法基本相似,也負(fù)責(zé)對(duì)參數(shù)進(jìn)行處理,只是該方法不會(huì)返回處理結(jié)果 -
XxxPredicate:這類接口中通常包含一個(gè)test()抽象方法,該方法通常用來(lái)對(duì)參數(shù)進(jìn)行某種判斷(test()方法的判斷邏輯由lambda表達(dá)式來(lái)實(shí)現(xiàn)(,然后返回一個(gè)Boolean值。該接口通常用于判斷參數(shù)是否滿足特定條件,經(jīng)常用于進(jìn)行篩濾數(shù)據(jù) -
XxxSuppliter:這類接口通常包含一個(gè)getAsXxx()抽象方法,該方法不需要傳入?yún)?shù),該方法會(huì)按某種邏輯算法(getAsXxx()方法的邏輯算法由lambda表達(dá)式來(lái)實(shí)現(xiàn))返回一個(gè)數(shù)據(jù)。
-
lambda表達(dá)式與匿名內(nèi)部類的聯(lián)系和區(qū)別
- lambda表達(dá)式時(shí)匿名內(nèi)部類的一種簡(jiǎn)化,可以部分取代匿名內(nèi)部類的作用
- 相同點(diǎn)
- lambda表達(dá)式和匿名內(nèi)部類一樣,都可以直接訪問(wèn)
effectively final的局部變量,以及外部類的成員變量(包括實(shí)例變量和類變量) - lambda表達(dá)式創(chuàng)建的對(duì)象與匿名內(nèi)部類生成的對(duì)象一樣,都可以直接調(diào)用從接口紅繼承的默認(rèn)方法
- lambda表達(dá)式和匿名內(nèi)部類一樣,都可以直接訪問(wèn)
- 區(qū)別
- 匿名內(nèi)部類可以為任意接口創(chuàng)建實(shí)例,不管接口包含多少個(gè)抽象方法,只要匿名內(nèi)部類實(shí)現(xiàn)所有的抽象方法即可;但lambda表達(dá)式只能為函數(shù)式接口創(chuàng)建實(shí)例
- 匿名內(nèi)部類可以為抽象類甚至普通類創(chuàng)建實(shí)例;但lambda表達(dá)式只能為函數(shù)式接口創(chuàng)建實(shí)例
- 匿名內(nèi)部類實(shí)現(xiàn)的抽象方法的方法體允許調(diào)用接口中定義的默認(rèn)方法;但lambda表達(dá)式的代碼塊不允許調(diào)用接口中定義的默認(rèn)方法
使用lambda表達(dá)式調(diào)用Arrays的類方法
-
Arrays類的有些方法需要Comparator、XxxOperator、XxxFunction等接口的實(shí)例,這些接口都是函數(shù)式接口
枚舉類
一個(gè)類的對(duì)象是有限而且固定的,即實(shí)例有限而且固定的類
手動(dòng)實(shí)現(xiàn)枚舉類
- 在早期代碼中,可能會(huì)使用簡(jiǎn)單的靜態(tài)常量來(lái)表示枚舉
- 定義類的方式實(shí)現(xiàn)
- 通過(guò)
private將構(gòu)造器隱藏起來(lái) - 把類所有可能實(shí)例都使用
public static final修飾的類變量來(lái)保存 - 如果有必要,提供一些靜態(tài)方法,允許其他程序根據(jù)特定參數(shù)來(lái)獲取與之匹配的實(shí)例
- 通過(guò)
- 通過(guò)定義類實(shí)現(xiàn)枚舉的代碼量比較大,實(shí)現(xiàn)起來(lái)也比較麻煩
枚舉類入門(mén)
- 關(guān)鍵字
enum(與class、interface關(guān)鍵字地位相同),定義枚舉類 - 一個(gè)源文件中最多只能定義一個(gè)
public訪問(wèn)權(quán)限的枚舉類,且該源文件也必須和枚舉類類名相同 - 與普通類的區(qū)別
- 枚舉類可以實(shí)現(xiàn)一個(gè)或多個(gè)接口,枚舉類默認(rèn)繼承了
java.lang.Enum類,而不是默認(rèn)繼承Object類,因此枚舉類不能顯式繼承其他父類-
java.lang.Enum類實(shí)現(xiàn)了java.lang.Serializable和java.lang.Comparable兩個(gè)接口
-
- 使用
enum定義、非抽象的枚舉類默認(rèn)會(huì)使用final修飾,因此枚舉類不能派生子類 - 枚舉類的構(gòu)造器只能使用
private訪問(wèn)控制符 - 枚舉類的所有實(shí)例必須在枚舉類的第一行顯式列出,否則這個(gè)枚舉類永遠(yuǎn)都不能產(chǎn)生實(shí)例
- 列出這些實(shí)例時(shí),系統(tǒng)會(huì)自動(dòng)添加
public static final修飾,無(wú)需顯式添加
- 列出這些實(shí)例時(shí),系統(tǒng)會(huì)自動(dòng)添加
- 枚舉類可以實(shí)現(xiàn)一個(gè)或多個(gè)接口,枚舉類默認(rèn)繼承了
- 枚舉類默認(rèn)提供了一個(gè)
values()方法,該方法可以很方便地遍歷所有的枚舉值 - 可通過(guò)
EnumClass.variable形式來(lái)訪問(wèn)枚舉實(shí)例 -
switch表達(dá)式還可使用枚舉類對(duì)象作為表達(dá)式,case表達(dá)式中的值直接使用枚舉值的名字 -
java.lang.Enum類提供的方法-
int compareTo(E o)- 該方法用于指定枚舉對(duì)象比較順序,同一個(gè)枚舉實(shí)例只能與相同類型的實(shí)例進(jìn)行比較。如果該枚舉對(duì)象位于指定枚舉對(duì)象之后,則返回正整數(shù);如果該枚舉對(duì)象位于指定枚舉對(duì)象之前,則返回負(fù)整數(shù),否則返回零
-
String name()- 返回此枚舉實(shí)例的名稱,這個(gè)名稱就是定義枚舉類時(shí)列出的所有枚舉值之一
- 應(yīng)優(yōu)先考慮使用
toString()方法
- 應(yīng)優(yōu)先考慮使用
- 返回此枚舉實(shí)例的名稱,這個(gè)名稱就是定義枚舉類時(shí)列出的所有枚舉值之一
-
int ordinal()- 返回枚舉值在枚舉類中的索引值(在枚舉聲明中的位置,第一個(gè)枚舉值的索引值為零)
-
String toString()- 返回枚舉常量的名稱,與
name方法相似,但toString()方法更常用
- 返回枚舉常量的名稱,與
-
public static <T extends Enum<T>> T valueOf(Class<T>enumType, String name)- 靜態(tài)方法,返回指定枚舉類中指定名稱的枚舉值。名稱必須與在枚舉類中聲明枚舉值時(shí)所用的標(biāo)識(shí)符完全匹配
-
枚舉類的成員變量、方法和構(gòu)造器
- 枚舉類產(chǎn)生對(duì)象的方式不同于普通類,枚舉類的實(shí)例只能是枚舉值,而不是隨意地通過(guò)
new來(lái)創(chuàng)建枚舉類對(duì)象 - 建議將枚舉類的成員變量都使用
private final修飾 - 構(gòu)造器
-
枚舉類實(shí)例名 (構(gòu)造器形參列表)- 必須定義和定義枚舉實(shí)例的形參列表相同的構(gòu)造器
-
實(shí)現(xiàn)接口的枚舉類
枚舉類也可以實(shí)現(xiàn)一個(gè)或多個(gè)接口
-
若需要每個(gè)枚舉值在調(diào)用該方法時(shí)呈現(xiàn)出不同的行為方式,則可以讓每個(gè)枚舉值分別來(lái)實(shí)現(xiàn)該方法
枚舉實(shí)例名 (構(gòu)造器形參列表) { // 實(shí)現(xiàn)接口的抽象方法 } 匿名內(nèi)部類
非抽象的枚舉類默認(rèn)使用
final修飾;對(duì)于一個(gè)抽象的枚舉類,只要它包含了抽象方法,系統(tǒng)會(huì)默認(rèn)使用abstract修飾
包含抽象方法的枚舉類
- 不能使用
abstract關(guān)鍵字將枚舉類定義成抽象類(系統(tǒng)自動(dòng)會(huì)添加abstract關(guān)鍵字),但因?yàn)槊杜e類需要顯式創(chuàng)建枚舉值,而不是作為父類,所以定義每個(gè)枚舉值時(shí)必須為抽象方法提供實(shí)現(xiàn),否則將出現(xiàn)編譯錯(cuò)誤
對(duì)象與垃圾回收
當(dāng)對(duì)象、數(shù)組等引用類型實(shí)體不再被任何引用變量引用時(shí),等待垃圾回收機(jī)制進(jìn)行回收
特征
- 垃圾回收機(jī)制只負(fù)責(zé)回收堆內(nèi)存的對(duì)象,不會(huì)回收任何物理資源(例如數(shù)據(jù)庫(kù)連接、網(wǎng)絡(luò)IO等資源)
- 程序無(wú)法精確控制垃圾回收的運(yùn)行,垃圾回收會(huì)在合適的時(shí)候進(jìn)行;當(dāng)對(duì)象永久性地失去引用后,系統(tǒng)就會(huì)在合適的時(shí)候回收它所占的內(nèi)存
- 在垃圾回收機(jī)制回收任何對(duì)象之前,總會(huì)調(diào)用它的
finalize()方法,該方法可能使對(duì)象重新復(fù)活(讓一個(gè)引用變量重新引用該對(duì)象),從而導(dǎo)致垃圾回收機(jī)制取消回收
對(duì)象在內(nèi)存中的狀態(tài)
- 當(dāng)一個(gè)對(duì)象在堆內(nèi)存中運(yùn)行時(shí),根據(jù)它被引用變量所引用的狀態(tài),可分為三種狀態(tài)
- 可達(dá)狀態(tài)
- 當(dāng)一個(gè)對(duì)象被創(chuàng)建后,若有一個(gè)以上的引用變量引用它,則這個(gè)對(duì)象在程序中處于可達(dá)狀態(tài),程序可通過(guò)引用變量來(lái)調(diào)用該對(duì)象的實(shí)例變量和方法
- 可恢復(fù)狀態(tài)
- 如果程序中某個(gè)對(duì)象不再有任何引用變量引用它,它就進(jìn)入了可恢復(fù)狀態(tài)
- 在這種狀態(tài)下,系統(tǒng)的垃圾回收機(jī)制準(zhǔn)備回收該對(duì)象所占用的內(nèi)存,在回收該對(duì)象之前,系統(tǒng)會(huì)調(diào)用所有可恢復(fù)狀態(tài)對(duì)象的
finalize()方法進(jìn)行資源清理。 - 如果系統(tǒng)在調(diào)用
finalize()方法時(shí)重新讓一個(gè)以引用變量引用該對(duì)象,則這個(gè)對(duì)象會(huì)再次變?yōu)榭蛇_(dá)狀態(tài);否則該對(duì)象將進(jìn)入不可達(dá)狀態(tài)
- 不可達(dá)狀態(tài)
- 當(dāng)對(duì)象與所有引用變量的關(guān)系都被切斷,且系統(tǒng)已經(jīng)調(diào)用所有對(duì)象的
finalize()方法后依然沒(méi)有使對(duì)象變成可達(dá)狀態(tài),那么這個(gè)對(duì)象將永久性地失去引用,最后變成不可達(dá)狀態(tài) - 只有當(dāng)一個(gè)對(duì)象處于不可達(dá)狀態(tài)時(shí),系統(tǒng)才會(huì)真正回收該對(duì)象所占有的資源
- 當(dāng)對(duì)象與所有引用變量的關(guān)系都被切斷,且系統(tǒng)已經(jīng)調(diào)用所有對(duì)象的
- 可達(dá)狀態(tài)
- 一個(gè)對(duì)象可以被一個(gè)方法的局部變量引用,也可以被其他類的類變量引用,或被其他對(duì)象的實(shí)例變量引用。
- 當(dāng)某個(gè)對(duì)象被其他類的類變量引用時(shí),只有該類被銷毀后,該對(duì)象才會(huì)進(jìn)入可恢復(fù)狀態(tài);當(dāng)某個(gè)對(duì)象被其他對(duì)象的實(shí)例變量引用時(shí),只有當(dāng)該對(duì)象被銷毀后,該對(duì)象才會(huì)進(jìn)入可恢復(fù)狀態(tài)
強(qiáng)制垃圾回收
- 程序只能控制一個(gè)對(duì)象何時(shí)不再被任何引用變量引用,絕不能控制它何時(shí)被回收
- 程序無(wú)法精確控制Java垃圾回收的時(shí)機(jī),但依然可以強(qiáng)制系統(tǒng)進(jìn)行垃圾回收
- 這種強(qiáng)制只是通知系統(tǒng)進(jìn)行垃圾回收,但系統(tǒng)是否進(jìn)行垃圾回收依然不確定
- 方式
- 調(diào)用
System類的gc()靜態(tài)方法:System.gc() - 調(diào)用
Runtime對(duì)象的gc()實(shí)例方法:Runtime.getRuntime().gc()
- 調(diào)用
-
java -verbose:gc 類名- 可以看到每次垃圾回收后的提示信息
- 這種強(qiáng)制只是建議系統(tǒng)立即進(jìn)行垃圾回收,垃圾回收機(jī)制會(huì)在收到通知后,盡快進(jìn)行垃圾回收
finalize方法
- 在垃圾回收機(jī)制回收某個(gè)對(duì)象所占用的內(nèi)存之前,通常要求程序調(diào)用適當(dāng)?shù)姆椒▉?lái)清理資源,在沒(méi)有明確指定清理資源的情況下,Java提供了默認(rèn)機(jī)制來(lái)清理該對(duì)象的資源,這個(gè)機(jī)制就是finalize()方法
- 方法原型
protected void finalize() throws Throwable-
throws Throwable表示可以拋出任何類型的異常
- 當(dāng)
finalize()方法返回后,對(duì)象消失,垃圾回收機(jī)制開(kāi)始執(zhí)行 - 任何Java類都可以重寫(xiě)Object類的
finalize()方法,在該方法中清理該對(duì)象占用的資源 - 如果程序終止之前始終沒(méi)有進(jìn)行垃圾回收,則不會(huì)調(diào)用失去引用對(duì)象的
finalize()方法來(lái)清理資源 - 垃圾回收機(jī)制何時(shí)調(diào)用對(duì)象的
finalize()方法是完全透明的,只有當(dāng)程序認(rèn)為需要更多的額外內(nèi)存時(shí),垃圾回收機(jī)制才會(huì)進(jìn)行垃圾回收 - 特點(diǎn)
- 永遠(yuǎn)不要主動(dòng)調(diào)用某個(gè)對(duì)象的
finalize()方法,該方法應(yīng)交給垃圾回收機(jī)制調(diào)用 -
finalize()方法何時(shí)被調(diào)用,是否被調(diào)用具有不確定性,不要把finalize()方法當(dāng)成一定會(huì)被執(zhí)行的方法 - 當(dāng)JVM執(zhí)行可恢復(fù)對(duì)象
finalize()方法時(shí),可能使該對(duì)象或系統(tǒng)中其他對(duì)象重新編程可達(dá)狀態(tài) - 當(dāng)JVM執(zhí)行
finalize()方法時(shí)出現(xiàn)異常時(shí),垃圾回收機(jī)制不會(huì)報(bào)告異常,程序繼續(xù)執(zhí)行
- 永遠(yuǎn)不要主動(dòng)調(diào)用某個(gè)對(duì)象的
- 強(qiáng)制垃圾回收機(jī)制調(diào)用可恢復(fù)對(duì)象的
finalize()方法Runtime.getRuntime().runFianlization();System.runFinaliaztion();
對(duì)象的軟、弱和虛引用
- 對(duì)于大部分而言,程序里會(huì)有一個(gè)引用變量引用該對(duì)象,這是最常見(jiàn)的引用方式
java.lang.ref包下提供3個(gè)類
-
SoftReference
- 軟引用
-
PhantomReference
- 虛引用
-
WeakReference
- 弱引用
-
強(qiáng)引用(StrongReference)
- Java程序中最常見(jiàn)的引用方式
- 程序創(chuàng)建一個(gè)對(duì)象,并把這個(gè)對(duì)象賦給一個(gè)引用變量,程序通過(guò)該引用變量來(lái)操作實(shí)際的對(duì)象
-
軟引用(SoftReference)
- 需要通過(guò)
SoftReference類來(lái)實(shí)現(xiàn),當(dāng)一個(gè)對(duì)象只有軟引用時(shí),它有可能被垃圾回收機(jī)制回收 - 對(duì)于只有軟引用的對(duì)象而言,當(dāng)系統(tǒng)內(nèi)存空間足夠時(shí),它不會(huì)被系統(tǒng)回收,程序也可使用該對(duì)象;當(dāng)系統(tǒng)內(nèi)存空間不足時(shí),系統(tǒng)可能會(huì)回收它
- 軟引用通常用于對(duì)內(nèi)存敏感的程序中
- 需要通過(guò)
-
弱引用(WeakReference)
- 弱引用通過(guò)
WeakReference類實(shí)現(xiàn),弱引用和軟引用很像,但弱引用的引用級(jí)別更低 - 對(duì)于只有弱引用的對(duì)象而言,當(dāng)系統(tǒng)垃圾回收機(jī)制運(yùn)行時(shí),不管系統(tǒng)內(nèi)存是否足夠,總會(huì)回收該對(duì)象所占用的內(nèi)存
- 必須等到系統(tǒng)垃圾回收機(jī)制運(yùn)行時(shí)才會(huì)被回收
- 弱引用通過(guò)
-
虛引用(PhantomReference)
- 虛引用通過(guò)
PhantomReference類實(shí)現(xiàn),虛引用完全類似于沒(méi)有引用 - 虛引用對(duì)對(duì)象本身沒(méi)有太大影響,對(duì)象甚至感覺(jué)不到虛引用的存在
- 如果一個(gè)對(duì)象只有一個(gè)虛引用時(shí),那么它和沒(méi)有引用的效果大致相同
- 虛引用主要用于跟蹤對(duì)象被垃圾回收的狀態(tài),虛引用不能單獨(dú)使用,虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用
- 虛引用通過(guò)
以上三個(gè)引用類型都包含了一個(gè)
get()方法,用于獲取被它們所引用的對(duì)象-
隊(duì)列引用
- 引用隊(duì)列由
java.lang.ref.ReferenceQueue類表示,它用于保存被回收后對(duì)象的引用 - 當(dāng)聯(lián)合使用軟引用、弱引用和引用隊(duì)列時(shí),系統(tǒng)在回收被引用的對(duì)象之后,將把被回收對(duì)象對(duì)應(yīng)的引用添加到關(guān)聯(lián)的引用隊(duì)列中
- 與軟引用和弱引用不同的是,虛引用在對(duì)象被釋放之前,將把它對(duì)應(yīng)的虛引用添加到它關(guān)聯(lián)的引用隊(duì)列中,這使得可以在對(duì)象被回收之前采取行動(dòng)
- 引用隊(duì)列由
軟引用和弱引用可以單獨(dú)使用,但虛引用不能單獨(dú)使用,單獨(dú)使用虛引用沒(méi)有太大的意義
虛引用的主要作用就是跟蹤對(duì)象被垃圾回收的狀態(tài),程序可以通過(guò)檢查與虛引用關(guān)聯(lián)的引用隊(duì)列中是否已經(jīng)包含了該虛引用,從而鏈接虛引用所引用的對(duì)象是否即將被回收
系統(tǒng)無(wú)法通過(guò)虛引用來(lái)獲得被引用的對(duì)象;當(dāng)程序強(qiáng)制垃圾回收后,只有虛引用引用的對(duì)象被垃圾回收,當(dāng)被引用的對(duì)象被回收后,對(duì)應(yīng)的虛引用將被添加到關(guān)聯(lián)的引用隊(duì)列
strictfp關(guān)鍵字
- 含義:FP-strict
- 精確浮點(diǎn)
- 使用
strictfp關(guān)鍵字來(lái)修飾類、接口或方法時(shí),在修飾的范圍內(nèi)Java的編譯器和運(yùn)行環(huán)境會(huì)完全依照浮點(diǎn)規(guī)范IEEE-754來(lái)執(zhí)行
native關(guān)鍵字
- 主要用于修飾一個(gè)方法,使用
native修飾的方法類似于一個(gè)抽象方法 - 與抽象方法不同的是,
native方法通常采用C語(yǔ)言實(shí)現(xiàn) - 如果某個(gè)方法需要利用平臺(tái)相關(guān)特性,或者訪問(wèn)系統(tǒng)硬件等,則可以使用
native修飾該方法,再把該方法交給C語(yǔ)言去實(shí)現(xiàn) - 一旦Java程序中包含了
native方法,這個(gè)程序?qū)⑹タ缙脚_(tái)的功能
JAR包
JAR文件的全稱是
Java Archive File,意思是Java檔案文件。通常JAR文件是一種壓縮文件;JAR文件ZIP文件的區(qū)別是在JAR文件中默認(rèn)包含了一個(gè)名為META-INF/MANIFEST.MF的清單文件,這個(gè)清單文件是生成JAR文件時(shí)由系統(tǒng)自動(dòng)創(chuàng)建的。
將開(kāi)發(fā)的應(yīng)用程序提供給別人使用,通常將這些類文件打包成一個(gè)JAR文件;別人在系統(tǒng)的CLASSPATH環(huán)境變量中添加這個(gè)JAR文件,則Java虛擬機(jī)就可以自動(dòng)在內(nèi)存中解壓這個(gè)JAR包,把JAR文件當(dāng)成一個(gè)路徑,在這個(gè)路徑中查找所需要的類或包層次對(duì)應(yīng)的路徑結(jié)構(gòu)。
使用JAR文件的好處:
- 安全。能夠?qū)AR文件進(jìn)行數(shù)字簽名,只讓能夠識(shí)別數(shù)字簽名的用戶使用里面的東西。
- 加快下載速度。在網(wǎng)上使用
Applet時(shí),如果存在多個(gè)文件而不打包,為了能夠把每個(gè)文件都下載到客戶端,需要為每個(gè)文件單獨(dú)建立一個(gè)HTTP連接。 - 壓縮。使文件變小,JAR的壓縮機(jī)制和ZIP完全相同
- 包封裝。能夠讓JAR包里的文件依賴于同一版本的類文件。
- 可移植性。JAR包作為嵌在Java平臺(tái)內(nèi)部的標(biāo)準(zhǔn),能夠在各種平臺(tái)上直接使用。
JAR命令
JAR使隨JDK自動(dòng)安裝的,在JDK安裝目錄下的bin目錄中,Windows下文件名未jar.exe,Linux下文件名為jar
-
創(chuàng)建JAR文件:
jar cf jarName.jar -C dist\.
該命令沒(méi)有顯示壓縮過(guò)程,執(zhí)行結(jié)果使將當(dāng)前路徑下的dist路徑下的全部?jī)?nèi)容生成一個(gè)jarName.jar文件。 -
創(chuàng)建JAR文件,并顯示壓縮過(guò)程:
jar cvf jarName.jar -C dist\.
該命令的結(jié)果與第一個(gè)命令相同,但是由于v參數(shù)的作用,顯示出了打包過(guò)程。 -
不使用清單文件:
jar cvfM jarName.jar -C dist\.
該命令的結(jié)果與第二個(gè)命令相似,其中M選項(xiàng)表明不生成清單文件。因此生成的JAR包中沒(méi)有META-INF/MANIFEST.MF文件。 -
自定義清單文件內(nèi)容:
jar cvfm jarName.jar MANIFEST.MF -C dist\.
運(yùn)行結(jié)果與第二個(gè)命令相似,其中m選項(xiàng)指定讀取用于清單文件信息。因此在生成的JAR包中青島文件META-INF/MANIFEST.MF的內(nèi)容有所不同,它會(huì)在原有清單文件基礎(chǔ)上增加MANIFEST.MF文件的內(nèi)容。
當(dāng)開(kāi)發(fā)者向MANIFEST.MF清單文件中增加自己的內(nèi)容時(shí),清單文件的內(nèi)容由如下格式的多個(gè)key-value對(duì)組成。
key:<空格>value
清單文件的內(nèi)容格式要求如下:- 每行只能定義一個(gè)
key-value對(duì),每行的key-value對(duì)之前不能有空格 - 每組
key-value對(duì)之間以;(英文冒號(hào)后緊跟一個(gè)英文空格)分隔 - 文件開(kāi)頭不能有空行
- 文件必須以一個(gè)空行結(jié)束
可以將上面文件保存在任意位置,以任意文件名存放。
- 每行只能定義一個(gè)
-
查看JAR包內(nèi)容:
jar tf jarName.jar
當(dāng)JAR包中的文件路徑和文件非常多時(shí),直接執(zhí)行該命令將無(wú)法查看到包的全部?jī)?nèi)容,此時(shí)可利用重定向?qū)@示結(jié)果保存到文件中。
jar tf jarName.jar > a.txt
執(zhí)行上面命令看不到任何輸出,但命令執(zhí)行結(jié)束后,將在當(dāng)前路徑下生成一個(gè)a.txt文件,該文件保存了包里的文件的詳細(xì)信息。 -
查看JAR包詳細(xì)內(nèi)容:
jar tvf jarName.jar
該命令與第五個(gè)命令基本相似,但它更詳細(xì)。 -
解壓縮:
jar xf jarName.jar
將jar文件解壓到當(dāng)前目錄下,不顯示任何信息。 -
帶提示信息解壓縮:
jar xvf jarName.jar
解壓縮效果與第七個(gè)命令相似,但系統(tǒng)會(huì)顯示解壓過(guò)程的詳細(xì)信息。 -
更新JAR文件:
jar uf jarName.jar Hello.class
更新JAR文件中的Hello.class文件;如果JAR包中已有Hello.class文件,則使用新的文件替換原來(lái)的文件;如果包中沒(méi)有Hello.class文件,則把文件添加到JAR文件中。 -
更新時(shí)顯示詳細(xì)信息:
jar uvf jarName.jar Hello.class
這個(gè)命令與第九個(gè)命令相似,也用于更新JAR包的文件,但它會(huì)顯示詳細(xì)信息。 -
創(chuàng)建多版本的JAR包:
jar cvf jarName.jar -C dist1\. --release 9 -C dist\.
多版本JAR包時(shí)JDK9新增的功能,它允許同一個(gè)JAR包中包含針對(duì)多個(gè)Java版本的class文件。JDK9為JAR命令增加了一個(gè)--release選項(xiàng),用于創(chuàng)建多版本JAR包,該選項(xiàng)的參數(shù)值必須大于或等于9。
在使用多版本JAR包之前,可以使用javac的--release選項(xiàng)針對(duì)指定Java進(jìn)行編譯。比如命令:javac --release 7 Test.java,這個(gè)命令代表使用Java7的語(yǔ)法來(lái)編譯Test.java文件。
創(chuàng)建可執(zhí)行的JAR包
當(dāng)一個(gè)應(yīng)用程序開(kāi)發(fā)成功后,大致有如下三種發(fā)布方式
使用平臺(tái)相關(guān)的編譯器將整個(gè)應(yīng)用編譯成平臺(tái)相關(guān)的可執(zhí)行性文件
為應(yīng)用編輯一個(gè)批處理文件,以Windows系統(tǒng)為例,批處理文件只需要定義如下命令:
java package.MainClass,當(dāng)用戶運(yùn)行這個(gè)批處理文件時(shí),系統(tǒng)將運(yùn)行程序的主類。如果不想保留運(yùn)行Java程序的命令行窗口,也可以在批處理文件中定義如下命令:start javaw package.MainClass-
將一個(gè)應(yīng)用程序制作成可執(zhí)行的JAR包,通過(guò)JAR包來(lái)發(fā)布應(yīng)用程序。
在Windows下安裝JRE時(shí),安裝文件會(huì)將*.jar文件映射成由javaw.exe打開(kāi)。
JAR命令有一個(gè)-e選項(xiàng),該選項(xiàng)指定JAR包中作為程序在入口的主類的類名,例如下命令:jar cvfe jarName.jar test.Test test,這個(gè)命令把test目錄下所有文件都?jí)嚎s到JAR包中,并指定使用test.Test類作為程序的入口。
運(yùn)行上面的JAR包有兩種方式:- 使用
java命令,語(yǔ)法是:java -jar jarName.jar - 使用
javaw命令,語(yǔ)法是:javaw jarName.jar
當(dāng)創(chuàng)建JAR包時(shí),所有類都必須放在與包結(jié)構(gòu)對(duì)應(yīng)的目錄結(jié)構(gòu)中,必須在JAR包下包含
*.class文件 - 使用