Java基礎類庫
本章思維導圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9MGVNFTUU10MFRVT3V1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLygjN2AzNwIjM0EjMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
使用者互動
使用Scanner擷取鍵盤輸入
- Scanner主要提供了兩個方法來掃描輸入
-
hasNextXxx();
- 是否還有下一個輸入項,其中
可以是Xxx
、int
等代表基本資料類型的字元串。long
- 是否還有下一個輸入項,其中
-
nextXxx();
- 擷取下一個輸入項。
的含義與前一個方法中的Xxx
相同。Xxx
- 擷取下一個輸入項。
-
預設情況下,Scanner使用空白(
空格
、
Tab
、
回車
)作為多個輸入項之間的分隔符。
如果希望改變Scanner的分隔符,使用方法
useDelimiter(String pattern);
Scanner的讀取操作可能被阻塞,Scanner的
hasNext();
和
next();
方法都有可能阻塞,
hasNext();
方法是否阻塞與和其相關的
next();
方法是否阻塞無關
為Scanenr設定分隔符使用
useDelimiter(String pattern);
方法即可,該方法的參數應該是一個正規表達式
- Scanner提供了兩個簡單的方法來逐行讀取
-
boolean hasNextLine();
- 傳回輸入源中是否還有下一行
-
String nextLine();
- 傳回輸入源中下一行的字元串
-
- Scanner不僅能讀取使用者的鍵盤輸入,還可以讀取檔案輸入。
- 隻要在建立Scanner對象時傳入一個
對象作為參數,就可以讓Scanner讀取該檔案的内容。File
- 隻要在建立Scanner對象時傳入一個
系統相關
System類
System類代表目前Java程式的運作平台,程式不能建立System類的對象,System類提供了一些類變量和類方法,允許直接通過System類來調用這些類變量和類方法。
- System類提供了代表标準輸入、标準輸出和錯誤輸出的類變量,并提供了一些靜态方法用于通路環境變量、系統屬性的方法,還提供了加載檔案和動态連結庫的方法。
- 加載檔案和動态連結庫主要對
方法有用,對于一些特殊的功能(如通路作業系統底層硬體裝置等)Java程式無法實作,必須借助C語言來完成,此時需要C語言為Java方法提供實作。native
-
- Java程式中聲明native修飾的方法,類似于
方法,隻有方法簽名,沒有實作。編譯該Java程式,生産一個abstract
檔案。class
- Java程式中聲明native修飾的方法,類似于
-
- 用
編譯第1步生産的javah
檔案,将生産一個class
檔案。.h
- 用
-
- 寫一個
檔案實作native方法,這一步需要包含第2步産生的cpp
檔案(這個.h
檔案中包含了JDK帶的.h
檔案)。jni.h
- 寫一個
-
- 将第3步的
檔案編譯成動态連結庫檔案。.cpp
- 将第3步的
-
- 在Java中用System類活動
方法或Runtime類的loadLibrary..()
方法加載第4步産生的動态連結庫檔案,Java程式中就可以調用這個native方法了。loadLibrary()
- 在Java中用System類活動
-
- 加載檔案和動态連結庫主要對
調用System類的
getenv()
、
getProperties()
、
getProperty()
等方法來通路程式所在平台的環境變量和系統屬性。
System類提供了通知系統進行垃圾回收的
gc()
方法,以及通知系統進行資源清理的
runFinalization()
方法。
- System類還有兩個擷取系統目前時間的方法
-
currentTimeMillis();
-
nanoTime();
- 它們都傳回一個
型整數;實際上它們都傳回目前時間與UTC1970年1月1日午夜的時間差,前者以毫秒作為機關,後者以納秒作為機關。long
- 這兩個方法傳回的時間粒度取決于底層的作業系統,可能所在的作業系統根本不支援以毫秒、納秒作為計時機關。
- 許多作業系統以幾十毫秒為機關測量時間,
方法不可能傳回精确的毫秒數;而currentTimeMillis()
方法很少用,因為大部分作業系統都不支援使用納秒作為計時機關。nanoTime()
-
System類的
in
、
out
、
err
分别代表系統的标準輸入(通常是鍵盤輸入)、标準輸出(通常是顯示器)和錯誤輸出流,并提供了
setIn()
、
setOut()
和
setErr()
方法來改變系統的标準輸入、标準輸出和标準錯誤輸出流。
System類還提供了一個
identityHashCode(Object x);
方法,該方法傳回指定對象的精确
hashCode
值,根據該對象的位址計算得到的
hashCode
值。
Runtime類與java9的ProcessHandle
Runtime類代表Java程式運作時的環境,每個Java程式都有一個與之對應的Runtime執行個體,應用程式通過該對象與其運作時環境相連。
應用程式不能建立自己的Runtime執行個體,但可以通過
getRuntime()
方法擷取與之關聯的Runtime對象。
Runtime類也提供了
gc()
方法或
runFinalization()
方法來通知系統進行垃圾回收、清理系統資源,并提供了
load(String filename)
和
loadLibrary(String libname)
方法來加載檔案和動态連結庫。
- Runtime類部分方法
-
availableProcessors();
-
freeMemory();
-
totalMemory();
-
maxMemory();
-
exec();
-
通過exec啟動平台上的指令之後,它就變成了一個程序,Java使用Process來代表程序。
Java9新增了一個
ProcessorHandle
接口,通過該接口可擷取程序的ID、父程序和後代程序;通過該接口的
onExit()
方法可在程序結束時完成某些行為。
ProcessorHandle
還提供了一個
ProcessorHandle.Info
類,用于擷取程序的指令、參數、啟動時間、累計運作時間、使用者等資訊。
常用類
Object類
- 常用方法
-
boolean equals(Object obj);
- 判斷指定對象與該對象是否相等。
-
protected void finalize();
- 當系統中沒有引用變量引用到該對象時,垃圾回收器調用此方法來清理該對象的資源。
-
Class<?> getClass();
- 傳回該對象的運作時類。
-
int hashCode();
- 傳回該對象的hashCode值。
-
String toString();
- 傳回該對象的字元串表示。
-
Java還提供了一個
protected
修飾的
clone()
方法,該方法用于幫助其他對象實作自我克隆,就是得到一個目前對象的副本,而且二者之間完全隔離。
- 自定義類實作克隆的步驟
-
- 自定義類實作
接口。這是一個标記行性的接口,實作接口的對象可以實作自我克隆,接口裡沒有定義任何方法。Cloneable
- 自定義類實作
-
- 自定義類實作自己的
方法。clone()
- 自定義類實作自己的
-
- 實作
方法時通過clone()
調用super.clone();
實作的Object
方法來得到該對象的副本,并傳回副本。clone()
- 實作
-
Object類提供的Clone機制隻對對象裡各執行個體變量進行簡單複制,如果執行個體變量的類型是引用類型,Object的Clone機制也隻是簡單地複制這個引用變量,這樣原有對象的引用類型的執行個體變量與克隆對象的引用類型的執行個體變量依然指向記憶體中的同一個執行個體。
Object類的
clone()
方法隻是一種淺克隆,隻克隆該對象的所有成員變量值,不會對引用類型的成員變量值所引用的對象進行克隆。
如果需要對對象進行深克隆,則需要進行遞歸克隆,保證所有引用類型的成員變量值所引用的對象都被複制了。
Objects類
Java7新增的一個類,提供了一些工具方法來操作對象,這些工具方法大多是空指針安全的。
Java為工具類的命名習慣是添加一個字母
s
,比如操作數組的工具類是
Arrays
,操作集合的工具類是
Collections
。
Java9改進的String、StringBuffer和StringBuilder類
Java提供了
String
、
StringBuffer
和
StringBuilder
三個類來封裝字元串,并提供了一系列方法來操作字元串對象。
String類是不可變類,即一旦一個String對象被建立以後,包含在這個對象的字元序列是不可改變的,直至這個對象被銷毀。
StringBuffer
對象則代表一個字元序列可變的字元串,當一個StringBuffer被建立以後,通過StringBuffer提供的
append()
、
insert()
、
reverse()
、
setCharAt()
、
setLength()
等方法改變這個字元串對象的字元序列。一旦通過StringBuffer生産了最終想要的字元串,就可以調用它的
toString()
方法将其轉換為一個String對象。
StringBuilder
類是JDK1.5新增的類,它也代表可變字元串對象。StringBuffer和StringBuilder基本相似,兩個類的構造器和方法也基本相同。不同的是,StringBuffer是線程安全的,而StringBuilder則沒有實作線程安全功能,是以性能略高。
String、StringBuffer、StringBuilder都實作了
CharSequence
接口,是以
CharSequence
可認為是一個字元串的協定接口。
- String類提供了大量構造器來建立String對象
-
:建立了一個包含0個的字元串序列的String對象。String()
-
:使用指定的字元集将指定的String(byte[] bytes, Charset charset)
數組解碼成一個新的String對象。byte[]
-
:使用平台預設的字元集将指定的String(byte[] bytes, int offset, int length)
數組從byte[]
開始、長度為offset
的子數組解碼成一個新的String對象。length
-
:使用指定的字元集将指定的String(byte[] bytes, int offset, int length, String charsetName)
數組從byte[]
開始、長度為offset
的子數組解碼成一個新的String對象。length
-
:使用指定的字元集将指定的String(byte[] bytes, String charsetName)
數組解碼成一個新的String對象。byte[]
-
:将指定的字元數組從String(char[] value, int offset, int count)
開始、長度為offset
的字元元素連綴成字元串。count
-
:根據字元串直接量來建立一個String對象。String(String original)
-
:根據String(StringBuffer buffer)
對象來建立對應的String對象。StringBuffer
-
:根據String(StringBuilder builder)
對象來建立對應的String對象。StringBuilder
-
- String類也提供了大量方法來操作字元串對象
-
:擷取字元串中指定位置的字元。char charAt(int index)
-
:比較兩個字元串的大小。如果兩個字元串的字元序列相等,則傳回0;不相等時,從兩個字元串第0個字元開始比較,傳回第一個不相等的字元差。另一種情況,較長字元串的前面部分恰巧是較短的字元串,則傳回它們的長度差。int compareTo(String anotherString)
-
:将該String對象和str連接配接在一起。String concat(String str)
-
:将該對象與StringBuffer對象sb進行比較,當它們包含的字元序列相同時傳回true。boolean contentEquals(StringBuffer sb)
-
:将字數組連綴成字元串。static String copy ValueOf(char[] data)
-
:将char數組的子數組中的元素連綴成字元串。static String copyValueOf(char[] data, int offset, int count)
-
:傳回該String對象是否以boolean endsWith(String suffix)
結尾。suffix
-
:将字元串與指定對象比較,如果二者包含的字元序列相等,則傳回true,否則傳回false。boolean equals(Object anObject)
-
:将字元串與boolean equalsIgnoreCase(String str)
忽略大小寫比較。str
-
:将該String對象轉換成byte[] getBytes()
數組。byte
-
:該方法将字元串中從void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
開始,到srcBegin
結束的字元複制到srcEnd
字元數組中,其中dst
為目标字元數組的起始複制位置。dstBegin
-
:找出int indexOf(int ch, int fromIndex)
字元在該字元串中從ch
開始第一次出現的位置。fromIndex
-
:找出int indexOf(String str)
子字元串在該字元串中第一次出現的位置。str
-
:找出int indexOf(String str, int fromIndex)
子字元串在該字元串中從str
開始第一次出現的位置。fromIndex
-
:找出int lastIndexOf(int ch)
字元在該字元串中最後一次出現的位置。ch
-
:找出int lastIndexOf(int ch, int fromIndex)
字元中從ch
在該字元串中最後一次出現的位置。fronIndex
-
:找出int lastIndexOf(String str)
子字元串在該字元串中最後一次出現的位置。str
-
:找出int lastIndexOf(String str, int fromIndex)
子字元串在該字元串中從str
開始後最後一次出現的位置。fromIndex
-
:傳回目前字元串長度。int length()
-
:将字元串中第一個String replace(char oldChar, char newChar)
替換成oldChar
。newChar
-
:該String對象是否以boolean startsWith(String prefix)
開始。prefix
-
:該String對象從boolean startsWith(String prefix, int toffset)
位置算起,是否以toffset
開始。prefix
-
:擷取從String substring(int beginIndex)
位置開始到結束的字元串。beginIndex
-
:擷取從String substring(int beginIndex, int endIndex)
位置開始到beginIndex
位置的子字元串。endIndex
-
:将該String對象轉換成char數組。char[] toCharArray()
-
:将字元串轉換成小寫。String toLowerCase()
-
:将字元串轉換成大寫。String toUpeprCase()
-
:一系列用于将基本類型值轉換為String對象的方法。static String valueOf(X x)
-
- StringBuffer、StringBuilder有兩個屬性:
和length
。capacity
- 其中
屬性表示其包含的字元串序列的長度。與String對象不同的是,StringBuffer、StringBuilder的length是可以改變的,可以通過length
、length()
方法來通路和修改其字元序列的長度。setLength(int len)
-
屬性表示StringBuilder的容量,capacity
通常比capacity
大,程式通常無需關心length
屬性。capacity
- 其中
Math類
Math類是一個工具類,它的構造器被定義成
private
的,是以無法建立Math類的對象;Math類中的所有方法都是類方法;還提供了的兩個類變量
PI
和
E
。
ThreadLocalRandom與Random
Random
類專門用于生成一個僞随機數,它有兩個構造器:一個構造器使用預設的種子(以目前時間作為種子),另一個構造器需要顯式傳入一個
long
型整數的種子。
ThreadLocalRandom
類是Java7新增的一個類,它是
Random
的增強版。在并發通路的環境下,使用
ThreadLocalRandom
來代替
Random
可以減少多線程資源競争,最終保證系統具有更好的線程安全性。
ThreadLocalRandom
類的用法和
Random
類的用法基本相似,它提供了一個靜态的
current()
方法來擷取
ThreadLocalRandom
對象,擷取該對象之後即可調用各種
nextXxx()
方法來擷取僞随機數。
Random使用一個48位的種子,如果這個類的兩個執行個體都是用同一個種子建立的,對它們以同樣的順序調用方法,則它們會産生相同的數字序列。
為避免兩個Random對象産生相同的數字序列,通常推薦使用目前時間作為Random對象的種子:
System.currentTimeMillis();
BigDecimal類
float
、
double
兩種基本浮點類型的浮點數容易引起精度丢失。
為了精确表示、計算浮點數,Java提供了
BigDecimal
類,該類提供了大量的構造器用于建立BigDecimal對象,包括把所有的基本數值類型變量轉換成一個BigDecimal對象,包括利用數字字元串、數字字元數組來建立BigDecimal對象。
不推薦使用
BigDecimal(double val);
構造器來建立對象,而是
BigDecimal(String val);
或
BigDecimal.valueOf(double value);
靜态方法來建立BigDecimal對象。
BigDecimal類提供了
add()
、
subtract()
、
multiply()
、
divide()
、
pow()
等方法對精确浮點數進行正常算術運算。
日期、時間類
Date類
Java提供了
Date
類來處理日期、時間,Date對象既包含日期,也包含時間。
Date類從JDK1.0起就開始存在了,但正因為它曆史悠久,是以它的大部分構造器、方法都已經過時,不在推薦使用了。
Date類提供了6個構造器,其中4個已經
Deprecated
(Java不在推薦使用,使用不再推薦的構造器時編譯會提出警告資訊,并導緻程式性能、安全性能等方面的問題),剩下的兩個構造器:
-
:生成一個代表目前日期時間的Date對象。該構造器在底層調用Date()
獲得System.currentMillis()
整數作為日期參數。long
-
:根據指定的Date(long date)
型整數來生成一個Date對象。該構造器的參數表示建立的Date對象和GMT1970年1月1日00:00:00之間的時間差,以毫秒作為計時機關。long
Date對象的大部分方法也
Deprecated
了,剩下為數不多的幾個方法:
-
:測試該日期是否在指定日期when之後。boolean after(Date when)
-
:測試該日期是否在指定日期when之前。boolean before(Date when)
-
:傳回該時間對應的long型整數,即從GMT1970-01-01 00:00:00到該Date對象之間的時間差,以毫秒作為計時機關。long getTime()
-
:設定Date對象的時間。void setTime(long time)
總體來說,Date是一個設計相當糟糕的類,Java官方推薦盡量少用Date的構造器和方法。
Calendar類
由于
Date
類在設計上存在一些缺陷,是以Java提供了
Calendar
類來更好地處理日期和時間。
Calendar
類本身是一個抽象類,它是所有月曆類的模闆,并提供了一些所有月曆通用的方法;但它本身不能直接執行個體化,程式隻能建立
Calendar
子類的執行個體,Java本身提供了一個
GregorianCalendar
類,一個代表格裡高利月曆的子類,它代表了通常所說的公曆。
Calendar
類是一個抽象類,是以不能使用構造器來建立Calendar對象。但它提供了幾個靜态
getInstance()
方法來擷取
Calendar
對象,這些方法根據
TimeZone
、
Locale
類來擷取特定的
Calendar
,如果不指定
TimeZone
、
Locale
,則使用預設的
TimeZone
、
Locale
來建立
Calendar
。
Calendar
和
Date
都是表示日期的工具類,他們直接可以自由轉換。
Calendar類提供了大量通路、修改日期時間的方法:
-
:根據月曆的規則,為給定的月曆字段添加或減去指定的時間量。void add(int field, int amount)
-
:傳回指定月曆字段的值。int get(int field)
-
:傳回指定月曆字段可能擁有的最大值。int getActualMaximum(int field)
-
:傳回指定月曆字段可能擁有的最小值。int getActualMinimum(int field)
-
:為給定的月曆字段設定為給定值。void set(int field, int value)
-
:設定Calendar對象的年、月、日三個字段的值。void set(int year, int month, int date)
-
:設定Calendar對象的年、月、日、時、分、秒6個字段的值。void set(int year, int month, int date, int hourOfDay, int minute, int second)
上面的很多方法都需要一個
int
類型的
field
參數,
field
是
Cakendar
類的類變量,如
Calendar.YEAR
、
Calendar.MONTH
等分别代表了年、月、日、小時、分鐘、秒等時間字段。
Calendar.MONTH
字段代表月份,月份的起始值不是1,而是0。
Calendar類的注意點:
-
與add
的差別roll
-
的功能非常強大,add(int field, int amount)
主要用于改變add
的特定字段的值。有兩條規則:Calendar
- 當被修改的字段超出它允許的範圍時,會發生進位,即上一級字段也會增大。
- 如果下一級字段也需要改變,那麼該字段會修正到變化最小的值。
-
的規則與roll()
的處理規則不同:當被修改的字段超出它允許的範圍時,上一級字段不會增大;下一級字段的處理規則與add()
相似。add()
-
- 設定
的容錯性Calendar
- Calendar有兩種解釋月曆字段的模式:
模式和lenient
模式。當處于non-lenient
模式時,每個時間字段可接受超過它允許範圍的值;當處于lenient
模式時,如果為某個時間字段設定的值超出了它允許的取值範圍,程式将會抛出異常。non-lenient
- Calendar有兩種解釋月曆字段的模式:
-
方法延遲修改set()
-
方法将月曆字段set(f, value)
更改為f
,此處它還設定了一個内部成員變量,以訓示月曆字段value
已經被更改。盡管月曆字段f
是立即更改的,但該f
所代表的時間不會立即修改,直到下次調用Calendar
、get()
、getTime()
、getTimeInMillis()
或add()
時才會重新計算月曆的時間。roll()
-
Java8新增的日期、時間包
Java8新增了一個java.time包,該包包含如下常用類:
-
:該類用于擷取指定時區的目前日期、時間。該類可取代System類的currentTimeMillis()方法,而且提供了更多方法來擷取目前日期、時間。該類提供了大量靜态方法來擷取Clock
對象。Clock
-
:該類代表持續時間。該類可以非常友善地擷取一段時間。Duration
-
:代表一個具體的時刻,可以精确到納秒。該類提供了靜态的Instant
方法來擷取目前時刻,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的時刻。除此之外,它還提供了一系列clock
方法在目前時刻基礎上減去一段時間,也提供了minusXxx()
方法在目前時刻基礎上加上一段時間。plusXxx()
-
:該類代表不帶時區的日期,例如1999-10-30。該類提供了靜态的LocalDate
方法來擷取目前日期,也提供了靜态的now()
方法來擷取目前now(Clock clock)
對應的日期。除此之外,它還提供了一系列clock
方法在目前年份基礎上減去幾年、幾月、幾周或幾日,也提供了minusXxx()
方法在目前年份基礎上加上幾年、幾月、幾周或幾日。plusXxx()
-
:該類代表不帶時區的時間,例如10:30:13。該類提供了靜态的LocalTime
方法來擷取目前時間,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的時間。除此之外,它還提供了一系列clock
方法在目前年份基礎上減去幾小時、幾分、幾秒等,也提供了minusXxx()
方法在目前年份基礎上加上加幾小時、幾分、幾秒等。plusXxx()
-
:該類代表不帶時區的日期、時間,例如1999-10-30T10:30:13。該類提供了靜态的LocalDateTime
方法來擷取目前日期、時間,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的日期、時間。除此之外,它還提供了一系列clock
方法在目前年份基礎上減去幾年、幾月、幾日幾小時、幾分、幾秒等,也提供了minusXxx()
方法在目前年份基礎上加上幾年、幾月、幾日幾小時、幾分、幾秒等。plusXxx()
-
:該類僅代表月日,例如–10-30。該類提供了靜态的MonthDay
方法來擷取目前月日,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的月日。clock
-
:該類僅代表年,例如1999。該類提供了靜态的Year
方法來擷取目前年份,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的年份。除此之外,它還提供了clock
方法在目前年份基礎上減去幾年,也提供了minusYears()
方法在目前年份基礎上加上幾年。plusYear()
-
:該類僅代表年月,例如1999-10。該類提供了靜态的YearMonth
方法來擷取目前年月,也提供了靜态的now()
方法來擷取now(Clock clock)
對應的年月。除此之外,它還提供了clock
方法在目前年月基礎上減去幾年、幾月,也提供了minusXxx()
方法在目前年月基礎上加上幾年、幾月。plusXxx()
-
:該類代表一個時區化的日期、時間。ZonedDateTime
-
:該類代表一個時區。ZoneId
-
:這是一個枚舉類,定義了周日到周六的枚舉值。DayOfWeek
-
:這是一個枚舉類,定義了一月到十二月的枚舉值。Month
-
正規表達式
正規表達式是一個強大的字元串處理工具,可以對字元串進行查找、提取、分割、替換等操作。
String
類裡也提供了如下幾個特殊方法:
-
:判斷該字元串是否比對指定的正規表達式。boolean matches(String regex)
-
:将該字元串中所有比對String replaceAll(String regex, String replacement)
的字串替換成regex
。replacement
-
:将該字元串中第一個比對String repalceFirst(String regex, String replacement)
的字串替換成regex
。replacement
-
:以String[] split(String regex)
作為分隔符,把該字元串分割成多個字串。regex
上面這些特殊的方法都依賴于Java提供的正規表達式支援,除此之外,Java還提供了
Pattern
和
Matches
兩個類專門用于提供正規表達式支援。
建立正規表達式
正規表達式所支援的合法字元:
-
:字元x(x可代表任何合法的字元)x
-
:八進制數0mnn所代表的字元\0mnn
-
:十六進制值0xhh所代表的字元\xhh
-
:十六進制值0xhhhh所代表的\uhhhh
字元Unicode
-
:制表符(’\u000A’)\t
-
:新行(換行)符(’\u000A’)\n
-
:回車符(’\u000D’)\r
-
:換頁符(’\u000C’)\f
-
:報警(bell)符(’\u0007’)\a
-
:Escape符(’\u001B’)\e
-
:\cx
對應的控制符。x值必須為x
或A~Z
之一。a~z
正規表達式中有一些特殊字元,這些特殊字元在正規表達式中有其特殊的用途,如果需要比對這些特殊字元,就必須首先将這些字元轉義,也就是在前面加一個反斜線(
\
)。
-
:比對一行的結尾。$
-
:比對一行的開頭。^
-
:标記子表達式的開始和結束位置。()
-
:用于确定中括号表達式的開始和結束位置。[]
-
:用于标記前面子表達式的出現頻度。{}
-
:指定前面子表達式可以出現零次或多次,*
-
:指定前面表達式可以出現一次或多次。+
-
:指定前面子表達式可以出現零次或一次。?
-
:用于轉義下一個字元,或指定八進制、十六進制字元。\
-
:指定兩項之間任選一項。|
預定義字元
-
:可以比對任何字元。.
-
:比對\d
的所有數字。0~9
-
:比對非數字。\D
-
:比對所有的空白字元,包括空格、制表符、回車符、換頁符、換行符等。\s
-
:比對所有的非空白字元。\S
-
:比對所有的單詞字元,包括0~9所有數字、26個英文字母和下劃線(_)。\w
-
:比對所有的非單詞字元。\W
方括号表達式
- 表示枚舉:例如
,表示f、x其中任意一個字元;[fx]
表示j、x其中任意一個字元。[jk]
- 表示範圍-:例如
,表示[a-f]
範圍内的任意字元;如a~f
,表示[a-cx-z]
、a~c
範圍内的任意字元。x~z
- 表示求否
:例如^
,表示非a、b、c的任意字元;[^abc]
,表示不是[^a-f]
範圍内的任意字元。a~f
- 表示與運算
:例如&&
,求[a-z&&[def]]
和a~z
的交集,表示d、e或f;[def]
,[a-z&&[^bc]]
範圍内的所有字元,除b和c之外,即a~z
。[ad-z]
- 表示并運算:并運算與前面的枚舉類似。例如
,表示[a-d[m-p]]
。[a-dm-p]
邊界比對符
-
:行的開頭^
-
:行的結尾$
-
:單詞的邊界\b
-
:非單詞的邊界\B
-
:輸入的開頭\A
-
:前一個比對的結尾\G
-
:輸入的結尾,僅用于最後的結束符。\Z
-
:輸入的結尾\z
數量辨別符
-
(貪婪模式):數量辨別符預設采用貪婪模式,除非另有表示。貪婪模式的表達式會一直比對下去,直到無法比對為止。Greedy
-
:X表達式出現零次或一次X?
-
:X表達式出現零次或多次X*
-
:X表達式出現一次或多次X+
-
:X表達式出現n次X{n}
-
:X表達式最少出現n次X{n,}
-
:X表達式最少出現n次,最多出現m次X{n,m}
-
-
(勉強模式):用問号字尾(Reluctant
)表示,它隻會比對最少的字元。也稱為最小比對模式。?
-
:X表達式出現零次或一次X??
-
:X表達式出現零次或多次X*?
-
:X表達式出現一次或多次X+?
-
:X表達式出現n次X{n}?
-
:X表達式最少出現n次X{n,}?
-
:X表達式最少出現n次,最多出現m次X{n,m}?
-
-
(占有模式):用加号字尾(Possessive
)表示,目前隻有Java支援占有模式,通常比較少用。+
-
:X表達式出現零次或一次X?+
-
:X表達式出現零次或多次X*+
-
:X表達式出現一次或多次X++
-
:X表達式出現n次X{n}+
-
:X表達式最少出現n次X{n,}+
-
:X表達式最少出現n次,最多出現m次X{n,m}+
-
使用正規表達式
一旦在程式中定義了正規表達式,就可以使用
Pattern
和
Matcher
來使用正規表達式。
Pattern
對象是正規表達式編譯後在記憶體中的表示形式,是以,正規表達式字元串必須先被編譯為Pattern對象,然後再利用Pattern對象建立對應的
Matcher
對象。執行比對所涉及的狀态保留在
Matcher
對象中,多個
Matcher
對象可共享同一個
Pattern
對象。
如果某個正規表達式僅需一次使用,則可直接使用Pattern類的靜态
matches()
方法,此方法自動把指定字元串編譯成匿名
Pattern
對象,并執行比對。
Pattern是不可變類,可供多個并發線程安全使用。
Matcher
類提供了如下幾個常用方法:
-
:傳回目标字元串中是否包含與find()
比對的子串。Pattern
-
:傳回上一次與group()
比對的子串。Pattern
-
:傳回上一次與start()
比對的子串在目标字元串中的開始位置。Pattern
-
:傳回上一次與end()
比對的子串在目标字元串中的結束位置加1。Pattern
-
:傳回目标字元串前面部分與lookingAt()
是否比對。Pattern
-
:傳回整個目标字元串與matches()
是否比對。Pattern
-
:将現有的reset()
對象應用于一個新的字元序列。Matcher
通過
Matcher
類的
find()
和
group()
方法可以從目标字元串中依次取出特定子串(比對正規表達式的子串)。
find()
方法依次查找字元串中與
Pattern
比對的子串,一旦找到對應的子串,下次調用
find()
方法時将接着向下查找。
find()
方法還可以傳入一個
int
類型的參數,帶
int
參數的
find()
方法将從該
int
索引處向下搜尋。
start()
和
end()
方法主要用于确定子串在目标字元串中的位置。
使用
find()
、
group()
方法逐項取出目标字元串中與指定正規表達式比對的子串,并使用
start()
、
end()
方法傳回子串在目标字元串中的位置。
matches()
和
lookingAt()
方法有點相似,隻是
matches()
方法要求整個字元串和
Pattern
完全比對時才傳回
true
,而
lookingAt()
隻要字元串以
Pattern
開頭就會傳回
true
。
reset()
方法可将現有的
Matcher
對象應用于新的字元序列。
從某個角度看,
Matcher
的
matches()
、
lookingAt()
和
String
類的
equals()
、
startWith()
有點相似。差別是
String
類的
equals()
和、
startWith()
都是與字元串進行比較,而
Matcher
的
matches()
和
lookingAt()
則是與正規表達式進行比對。
String
類裡也提供了
matches()
方法,該方法傳回該字元串是否比對指定的正規表達式。
還可以利用正規表達式對目标字元串進行分割、查找、替換等操作。
Matcher
類提供了
replaceAll(String replacement)
把字元串中所有與正規表達式比對的子串替換成
replacement
,還提供了一個
replaceFirst(String replacement)
方法,該方法僅替換第一個比對的子串。
String
類也提供了
replaceAll()
、
replaceFirst()
、
split()
等方法。
變量處理和方法處理
Java9引入了一個新的
VarHandle
類,并增強了原有的
MethodHandle
類。通過這兩個類,允許Java像動态語言一樣引用變量、飲用方法,并調用它們。
Java9增強的
MethodHandle
-
為Java增強了方法引用的功能,方法引用的概念有點類似于C的函數指針。這種方法引用是一種輕量級的引用方式,它不會檢查方法的通路權限,也不管方法所屬的類、執行個體方法或靜态方法,MethodHandle
就是簡單代表特定的方法,并可通過MethodHandle
來調用方法。MethodHandle
- 為了使用
類,還涉及如以下幾個類:MethodHandle
-
:MethodHandles
的工廠類,它提供了一系列靜态方法用于擷取MethodHandle
。MethodHandle
-
:MethodHandles.Lookup
靜态内部類也是Lookup
、MethodHandle
的工廠類,專門用于擷取VarHandle
和MethodHandle
。VarHandle
-
:代表一個方法類型。MethodType
根據方法的形參、傳回值類型來确定方法類型。MethodType
- 程式使用
對象根據類、方法名、方法類型來擷取MethodHandles.Lookup
對象。擷取的方法名是一個字元串類型,這意味着通過MethodHandle
可以讓Java動态調用某個方法。MethodHandle
-
Java9增強的
VarHandle
-
主要用于動态操作數組的元素或對象的成員變量。VarHandle
和VarHandle
非常相似,它也需要通過MethodHandle
來擷取執行個體,接下來調用MethodHandles
的方法即可動态操作指定數組的元素或指定對象的成員變量。VarHandle
Java9改進的國際化與格式化
國際化是指應用程式運作時,可根據用戶端請求來自的國家/地區、語言的不同而顯示不同的界面。
Java國際化的思路:
- Java程式的國際化思路是将程式中的标簽、提示等資訊放在資源檔案中,程式需要支援哪些國家、語言環境,就對應提供的資源檔案。
- 資源檔案是
對,每個資源檔案中的key-value
是不變的,但key
則随不同的國家、語言而改變。value
- Java程式的國際化主要是通過如下三個類完成:
-
:用于加載國家、語言資源包。java.util.ResourceBundle
-
:用于封裝特定的國家/區域、語言環境。java.util.Locale
-
:用于格式化帶占位符的字元串。java.text.MessageFormat
-
- 資源檔案的命名可以有如下三種形式:
-
baseName_language_country.properties
-
baseName_language.properties
-
baseName.properties
-
- 其中
是資源檔案的基本名,使用者可随意指定;而baseName
和language
都不可随意變化,必須是Java所支援的語言和國家。country
Java支援的國家和語言:
- 可調用
類的Locale
方法,該方法傳回一個getAvailableLocales()
數組,該數組包含了Java所支援的國家和語言。Locale
完成程式國際化:
- 為了讓字元串常量可以改變,可以将需要輸出的各種字元串(不同的國家/語言環境對應不同的字元串)定義在資源包中。
- Java9支援使用
字元集來儲存屬性檔案,這樣在屬性檔案中就可以直接包含非西歐字元。UTF-8
- Java9程式國際化的關鍵類是
,它有一個靜态方法:ResourceBundle
,該方法将根據getBUndle(String baseName, Locale locale)
加載資源檔案,而Locale
封裝了一個國家、語言。Locale
使用
MessageFormat
處理包含占位符的字元串:
- 如果需要輸出的消息中必須包含動态的内容,可以使用帶占位符的消息。
- 例如:
。當程式使用msg=你好!{0}!今天是{1}
的ResourceBundle
方法來取出getString()
對應的字元串時,程式還需要為msg
和{0}
兩個占位符指派。{1}
- 此時需要使用
類,該類包含一個有用的靜态方法:MessageFormat
-
:傳回後面的多個參數值填充前面的format(String pattern, Object... values)
字元串,其中pattern
不是正規表達式,而是一個帶占位符的字元串。patter
-
使用類檔案代替資源檔案:
除使用屬性檔案作為資源檔案外,
Java
也允許使用類檔案代替資源檔案,即将所有的
key-value
對存入
class
檔案。
使用類檔案來代替資源檔案必須滿足以下條件:
- 該類的類名必須是
,這與屬性檔案的命名相似。baseName_language_country
- 該類必須繼承
,并重寫ListResourceBundle
方法,該方法傳回getContents()
數組,該數組的每一項都是Object
對。key-value
如果系統同時存在資源檔案、類檔案,系統将以類檔案為主,而不會調用資源檔案。
對于簡體中文的
Locale
,
ResourceBundle
搜尋資源檔案的順序是:
-
baseName_zh_CN.class
-
baseName_zh_CN.properties
-
baseName_zh.class
-
baseName_zh.properties
-
baseName.class
-
baseName.properties
Java9新增的日志API
Java9強化了原有的日志API,這套日志API隻是定義了記錄消息的最小API,開發者可将這些日志消息路由到各種主流的日志架構(如
SLF4J
、
Log4J
等),否則預設使用Java傳統的
java.util.logging
日志
API
。
這套日志API的用法非常簡單,隻要兩步即可:
- 調用
類的System
方法擷取getLogger(String name)
對象System.Logger
- 調用
對象的System.Logger
方法輸出日志。該方法的第一個參數用于指定日志級别。log()
- 日志級别:
- Java9日志級别
-
:最低級别,系統将會輸出所有日志資訊。ALL
-
:輸出系統的各種跟蹤資訊。TRACE
-
:輸出系統的各種調試資訊。DEBUG
-
:輸出系統内需要提示使用者的提示資訊。INFO
-
:隻輸出系統内警告使用者的警告資訊。WARNING
-
:隻輸出系統發生錯誤的錯誤資訊。ERROR
-
:關閉日志輸出。OFF
-
- 傳統日志級别
-
:最低級别,系統将會輸出所有日志資訊。ALL
-
:輸出系統的各種跟蹤資訊。FINER
-
:輸出系統的各種調試資訊。FINE
-
:輸出系統内需要提示使用者的提示資訊。INFO
-
:隻輸出系統内警告使用者的警告資訊。WARNING
-
:隻輸出系統發生錯誤的錯誤資訊。SERVRE
-
:關閉日志輸出。OFF
-
- Java9日志級别
- 日志級别:
Java9的日志API也支援國際化,
System
類除使用簡單的
getLogger(String name)
方法擷取
System.Logger
對象之外,還可使用
getLogger(String name, ResourceBundle bundle)
方法來擷取該對象,該方法需要傳入一個國際化語言資源包,這樣該
Logger
對象即可根據
key
來輸出國際化的日志資訊。
使用 NumberFormat
格式化數字
NumberFormat
MessageFormat
是抽象類
Format
的子類,
Format
抽象類還有兩個子類:
NumberFormat
和
DateFormat
,它們分别用以實作數值、日期的格式化。
NumberFormat
、
DateFormat
可以将數值、日期轉換成字元串,也可以将字元串轉換成數值、日期。
NumberFormat
和
DateFormat
都包含了
format()
和
parse()
方法,其中
format()
用于将數值、日期格式化成字元串,
parse()
用于将字元串解析成數值、日期。
NumberFormat
也是一個抽象基類,是以無法通過它的構造器來建立
NumberFormat
對象,它提供了如下幾個類方法來得到
NumberFormat
對象:
-
:傳回預設getCurrencyInstance()
的貨币格式器。也可以在調用該方法時傳入指定的Locale
,則擷取指定Locale
的貨币格式器。Locale
-
:傳回預設getIntegerInstance()
的整數格式器。也可以在調用該方法時傳入指定的Locale
,則擷取指定Locale
的整數格式器。Locale
-
:傳回預設getNumberInstance()
的通用數值格式器。也可以在調用該方法時傳入指定的Locale
,則擷取指定的Locale
的通用數值格式器。Locale
-
:傳回預設的getPercentInstance()
的百分數格式器。也可以在調用該方法時傳入指定的Locale
,則擷取指定的Locale
的百分數格式器。Locale
一旦獲得了
NumberFormat
對象後,就可以調用它的
format()
方法來格式化數值,包括整數和浮點數。
使用 DateFormat
格式化日期、時間
DateFormat
- 與
相似的是,NumberFormat
也是一個抽象類,它也提供了如下幾個類方法用于擷取DateFormat
對象:DateFormat
-
:傳回一個日期格式器,它格式化後的字元串隻有日期,沒有時間。該方法可以傳入多個參數,用于指定日期樣式和getDateInstance()
等參數;如果不指定這些參數,則使用預設參數。Locale
-
:傳回一個時間格式器,它格式化後的字元串隻有時間,沒有日期。該方法可以傳入多個參數,用于指定時間樣式和getTimeInstance()
等參數;如果不指定這些參數,則使用預設參數。Locale
-
:傳回一個日期、時間格式器,它格式化後的字元串既有日期,也有時間。該方法可以傳入多個參數,用于指定日期樣式、時間樣式和getDateTimeInstance()
等參數;如果不指定這些參數,則使用預設參數。Locale
-
上面三個方法可以指定日期樣式、時間樣式參數,它們是
DateFormat
的4個靜态常量:
FULL
、
LONG
、
MEDIUM
和
SHORT
,通過這4個樣式參數可以控制生成的格式化字元串。
DateFormat
的
parse()
方法可以把一個字元串解析成
Date
對象,但它要求被解析的字元串必須符合日期字元串的要求,否則可能抛出
ParseException
異常。
使用 SimpleDateFormat
格式化日期
SimpleDateFormat
DateFormat
的
parse()
方法可以把字元串解析成
Date
對象,但
parse()
方法不夠靈活,它要求被解析的字元串必須滿足特定的格式;為了更好地格式化日期、解析日期字元串,Java提供了
SimpleDateFormat
類。
-
是SimpleDateFormat
的子類。DateFormat
-
可以非常靈活地格式化SimpleDateFormat
,也可以用于解析各種格式的日期字元串。建立Date
對象時需要傳入一個SimpleDateFormat
字元串,這個pattern
不是正規表達式,而是一個日期模闆字元串。pattern
Java8新增的日期、時間格式器
java.time.format
包下提供了一個
DateTimeFormatter
格式器類,該類相當于
DateFormat
和
SimpleDateFormat
的合體。
DateTimeFormatter
不僅可以将日期、時間對象格式化成字元串,也可以将特定格式的字元串解析成日期、時間對象。
為了使用
DateTimeFormatter
進行格式化或解析,必須先擷取
DateTimeFormatter
對象,擷取對象有如下三種常見的方式:
- 直接使用靜态常量建立
格式器。DateTimeFormatter
類中包含了大量形如DateTimeFormatter
、ISO_LOCAL_DATE
、ISO_LOCAL_TIME
等靜态常量,這些靜态常量本身就是ISO_LOCAL_DATE_TIME
執行個體。DateTimeFormatter
- 使用代表不同風格的枚舉值來建立
格式器。在DateTimeFormatter
枚舉類中定義了FormatStyle
、FULL
、LONG
、MEDIUM
四個枚舉值,它們代表日期、時間不同的風格。SHORT
- 根據模式字元串來建立
格式器。類似于DateTimeFormatter
,可以采用模式字元串來建立SimpleDateFormat
。DateTimeFormatter
使用DateTimeFormatter完成格式化
使用
DateTimeFormatter
将日期、時間(
LocalDate
、
LocalDateTime
、
LocalTime
等執行個體)格式化為字元串,可通過如下兩種方式:
- 調用
的DateTimeFormatter
方法執行格式化,其中format(TemporalAccessor temporal)
、LocalDate
、LocalDateTime
類都是LocalTime
接口的實作類。TemporalAccessor
- 調用
、LocalDate
、LocalDateTime
等日期、時間對象的LocalTime
方法執行格式化。format(DateTimeFormatter formatter)
DateTimeFormatter
則提供了一個
toFormat()
方法,該方法可擷取
DateTimeFormatter
對應的
Format
對象。
使用DateTimeFormatter解析字元串
使
DateTimeFormatter
将指定格式的字元串解析成日期、時間對象(
LocalDate
、
LocalDateTime
、
LocalTime
等執行個體),可通過日期、時間對象提供的
parse(CharSequence text, DateTimeFormatter formatter)
方法進行解析。