目錄
本系列將會介紹 Java SE 7 中的新功能和改進。首篇為概觀,其後的篇幅將會從本篇中挑出重要的部分加以詳細解說及示範。
注意:Java SE 7 中目前已發現 HotSpot 對迴圈最佳化後會在 server 模式下造成 bug。最好情況是 JVM crash(至少你知道程式掛了),最壞情況是迴圈不正確執行導致錯誤的結果(程式繼續跑但內部資料爛掉了)。在 Java SE 6 中此功能預設是關閉的,但在 Java SE 7 預設開啟。目前不建議將 Java SE 7 使用在商業用途,請改用 Java SE 7 Update 2 或其後的版本。
附註:若必須使用 Java SE 7,又要避免上述錯誤發生的話,可以在啟動程式時加上 -XX:-UseLoopPredicate
參數,藉以避免 JVM 對迴圈做最佳化。(感謝 Hao Cheng Lee 提出)
Swing
JLayer
類別
JLayer
類別是一個靈活強大的 Swing 裝飾元件。它可以讓你在其他元件上描繪並回應元件事件,而無需直接地修改底層元件。更多訊息請參見 Java Tutorials 中的如何使用 JLayer 來裝飾元件。
Nimbus 介面外觀
Nimbus 介面外觀(Look & Feel)已經從 com.sun.java.swing
搬到標準的 API 命名空間 javax.swing
;請參見 javax.swing.plaf.nimbus
。雖然它並不是預設的外觀,但你仍然可以很輕易地使用它。Java Tutorials 中的 Nimbus 介面外觀可取得更多資訊,以及在你的應用程式中用三種不同方式啟用 Nimbus 的範例。
重量級與輕量級元件
從前從前,在同一個容器中混合重量級(AWT)及輕量級(Swing)元件會造成問題。然而,在 Java SE 7 中已經可以很輕易地達到重量級和輕量級元件的混用。
多邊形及半透明視窗
Java SE 7 版本支援具透明度以及非矩形的視窗。請參見 Java Tutorials 中的如何建立半透明和多邊形視窗。
在 JColorChooser
類別中使用 HSL 調色盤(色調-飽和度-亮度)
HSV 分頁已加入 JColorChooser
類別裡,可允許使用者用 HSL 色彩模式來選擇顏色。
IO 及 NIO
java.nio.file
和與它相關的 java.nio.file.attribute
中提供了各式各樣的檔案 IO 支援,以及檔案系統存取。JDK 7 中同時也可找到 ZIP 檔案系統供應器。另外也包含了非同步的 IO 操作。下列資源提供了更多資訊:
- Java Tutorials 中的 File I/O(NIO 2.0 功能):NIO 支援非阻斷式 IO。
- 開發客製化的檔案系統供應器
- ZIP 檔案系統供應器
- 目錄
/sample/nio/chatserver/
下包含了示範java.nio.file
中新 API 的範例。 - 目錄
/demo/nio/zipfs/
下包含了示範 NIO 2.0 NFS (網路檔案系統) 的範例。
網路
新增 URLClassLoader.close()
方法。此方法有效地解決了問題:如何支援更新過後的類別實作和資源,尤其是從特殊代碼庫中載入的,像是 JAR 檔。請參見關閉 URLClassLoader
。
Sockets Direct 協定(SDP)提供高效網路連線存取的能力。請參見 Java Tutorials 中的瞭解 Sockets Direct Protocol。
安全性
橢圓曲線密碼學(Elliptic Curve Cryptography,簡稱 ECC)
新的原生供應器已加進 Java SE 7 中,並提供數個以 ECC 為基礎的演算法(ECDSA/ECDH)。請參見 Java PKCS#11 參考指南中的 Sun PKCS#11 供應器所支援的演算法。
關閉 CertPath 演算法
現在可以關閉不牢固的加密演算法。例如,已不再被認為是安全的 MD2 摘要演算法。Java SE 7 提供一套機制來拒絕在憑證路徑處理和 TLS 握手連線中使用特定的演算法。請參見 Java PKI 程式設計師指南中的附錄 D: 關閉加密演算法,以及 Java Secure Socket Extension (JSSE) 參考指南中的已關閉的加密演算法。
JSSE (SSL/TLS)
TLS 1.1
SunJSSE 現在支援 RFC 4346 中的 TLS 1.1。最重要的更新是針對密碼字段鏈結(Cipher block chaining,CBC)攻擊的保護措施。
TLS 1.2
SunJSSE 現在支援 RFC 5246 中的 TLS 1.2。除此之外,它可指定不同的內部雜湊演算法、增加了新的密碼套件、並包含了改進過後的加密靈活度,尤其是商議加密演算法。
摒棄不堅固的密碼套件
像是 RFC 4346、RFC 5246 以及 RFC 5469,有些密碼套件已經是過時且不應再被使用的。這些過時的套件在 SunJSSE 中已預設關閉。更多細節請查閱有關於 SunJSSE 供應器的文件中的密碼套件清單。
連線敏感的信託管理
現在信託管理者和金鑰管理者雙方都有能力檢驗 TLS 連線中的參數,明確地說是在握手階段時連線內的 SSLSession
。例如,信託管理者可能會限制憑證的類型必須列在有效的簽名演算法清單中。
終端查驗
終端識別演算法可以被指定去查驗遠端電腦的主機位址需與其提供的憑證相符。此種查驗類型早先已加入 HTTPS 協定(參見 HttpsURLConnection
和 HostnameVerifier
),而現在它已經在 TLS 層級上列為可選項目。
TLS 重新商議
Java SE 支援 RFC 5746,它修正了 TLS 協定中一些重新商議的問題。
預設關閉 SSLv2Hello
在 Java SE 7 中,SSLv2Hello 已從預設開啟的協定清單中移除。
關閉演算法
不堅固的加密演算法現在已可關閉,如同上述所說明的。
伺務器名稱指示(Server Name Indication,簡稱 SNI)的 JSSE 客戶端
Java SE 7 支援在 JSSE 客戶端中的 SNI 擴展。SNI 請參見 RFC 4366。它可以讓 TLS 客戶端連線到虛擬伺服器上。
更牢固的 EncryptedPreMasterSecret 版本數量驗証
Java SE 7 限縮了在 TLS 1.1 及 TLS 1.2 握手階段中的版本數量驗證。請參見 JSSE 參考指南。
並行工具
以 ForkJoinPool
類別為基礎的 fork/join 框架實作了 Executor
介面。它被設計成可有效地使用執行緒連線池來完成大量的任務。一種工作竊取(work-stealing)的技術可以讓所有的執行緒都處在忙碌的狀態,藉以達到多處理器的完整優勢。請參見 Java Tutorials 中的 Fork/Join。另外 /sample/forkjoin/
目錄下亦包含了 fork/join 框架的範例。
本地執行緒的偽亂數產生器 ThreadLocalRandom
類別使用偽亂數來消除執行緒之間的衝突。請參見並行隨機亂數。
靈活且可複用的 Phaser
類別是新的同步關卡(barrier),類似於 CyclicBarrier
。
新的傳輸佇列 TransferQueue
和並行性的雙向連結佇列 ConcurrentLinkedDeque
。
多樣化網際網路應用程式(Rich Internet Applications,簡稱 RIA)及部署
- 可拖曳的 applet 視窗現在可以使用預設或客製的標題,請參見開發可拖曳的 Applet 中的要求和客製化 Applet 裝飾元件。
- 下列改進已加入了 JNLP 檔案語法中,請參見 JNLP 檔案語法:
- 現在可以在
information
及resources
元素中的os
屬性中包含特定的 Windows 版本,像是 Windows Vista 或 Windows 7。 - 應用程式可以在
shortcut
元素的install
屬性中指定它們的安裝需求。已安裝的應用程式在 Java Web Start 快取被清除時將不會被一併移除,但可以使用 Java Control Panel 來明確指定去移除它們。 - Java Web Start 應用程式可以直接部署而無需指定
codebase
屬性,請參見不指定 Codebase 的部署方式。
- 現在可以在
- JNLP 檔案現在可以內嵌在 HTML 頁面中,請參見內嵌 JNLP 檔案到 Applet 標籤裡。
- 當 applet 正在載入時,你可以檢查它的狀態變數,來決定它是否已準備好去處理由 JavaScript 程式碼發出的請求。請參見用事件處理器來管理初始時期狀態。
- 現在你可以控制 applet 的視窗樣式及標題,不論是由捷徑啟動的,或是被拖曳到瀏覽器外的。請參見開發可拖曳的 Applet 中的要求和客製化 Applet 裝飾元件。
Java 2D
基於 XRender 的貼圖管線
現在基於 XRender 的新 Java 2D 貼圖管線已支援新式的 X11 桌面,提供加強過後的圖形效能,可存取大部份現今 GPU 的功能。此管線預設是關閉狀態,但可藉由設定命令列參數 {css:span=code}-Dsun.java2d.xrender=true{css} 來開啟。舊的 X11 組態可能無法支援 Xrender。詳盡格式 {css:span=code}-Dsun.java2d.xrender=True{css} 可發送一則訊息到標準輸出中,用來指出管線是否已實際啟動。請參見 {link:Java 2D 技術中的系統變數|http://download.oracle.com/javase/7/docs/technotes/guides/2d/flags.html#xrender}中有關 {css:span=code}xrender{css} 部份。
支援 OpenType/CFF 字型
JDK 現在會列舉出並顯示已安裝的 OpenType/CFF 字型,藉由呼叫像是 GraphicsEnvironment.getAvailableFontFamilyNames()
之類的函式;這些字型同時也會被 Font.createFont()
方法識別出來。請參見 Java Tutorials 中的選擇字型。
TextLayout
支援藏文字母表
TextLayout
支援藏文字母表。
支援 Linux 字型
對於 Solaris 及 Windows,JDK 的邏輯字型已在 fontconfig.properties
檔案中明確指定。而在其他各種不同的 Linux 實作品中,無法保証某特定的字型是否存在以支援特定的地區。自 Java SE 7 起,針對無法識別的 Linux 平台,可使用 libfontconfig
字型組態 API 來選擇該用何種字型去對應邏輯字型。請參見 Fontconfig。
Java XML – JAXP, JAXB, and JAX-WS
JAXP
- Java SE 7 現在包含了 Java API for XML Processing(JAXP)1.4.5 版。
- 和前一版比起來,有許多的臭蟲修正和一些改進,特別是一致性、安全性和效能。
- 雖然規格仍是 JAXP 1.4,但是 StAX 已經依照 JSR 173 Maintenance Review 3 而升級到 StAX 1.2 版。
更多資訊請參考 JAXP 1.4.5 Release Notes 和 JAXP 1.4.5 Change log。
JAXB
Java SE 7 支援 Java Architecture for XML Binding(JAXB)2.2.3 版。更多資訊請參考 JAXB Change log 中 JAXB RI 2.2 及更新版的部分。
JAX-WS
Java SE 7 支援 Java API for XML Web Services(JAX-WS)2.2.4 版。更多資訊請參考 JAX-WS Change log 中 JAX-WS RI 2.2 及更新版的部份。
國際化
Unicode 6.0.0 中新的字碼表和字元
Java SE 7 的早期版本中加入了 Unicode 5.1.0 的支援,而 Java SE 7 的最終版本支援 Unicode 6.0.0。Unicode 6.0.0 是 Unicode 標準的主要版本,不但支援了兩千個以上的額外字元,而且也新增了屬性和資料檔案。
Java Tutorials 中有新的一節討論 Unicode。
目錄 /demo/jfc/Font2DTest/
下包含了 Java 針對 Unicode 6.0 支援的相關範例。
ISO 4217 貨幣代碼的延伸支援
貨幣經由 ISO 4217 代碼辨別。這些代碼由外部的代理機構維護,並且獨立於 Java SE 平台外釋出。自 Java SE 7 起,將可以提供新的貨幣而無需釋出新版的 JDK。
若要在執行時期間替換預設貨幣,可事先建立一份名為 /lib/currency.properties
的特性檔。這份檔案需包含 ISO 3166 國家代碼以及 ISO 4217 貨幣資料的「鍵/值配對」。數值的部分由三項以逗號區分的 ISO 4217 貨幣數值所組成:字母代碼、數字代碼、以及最小單位。以 # 符號開頭的每一行皆會被視為註解。例如:
# Sample currency property for Japan
JP=JPZ,999,0
本功能的新 API 包括了下列方法,全部都位在 Currency
類別中:
getAvailableCurrencies()
:傳回可用貨幣的集合getNumericCode()
:傳回此貨幣在 ISO 4217 中的數值代碼getDisplayName()
:取得在預設地區下,能顯示此貨幣的合適名稱getDisplayName(Locale)
:取得在指定的地區下,能顯示此貨幣的合適名稱
分類 Locale
支援
預設地區可獨立地設定成兩種使用型態:format 使用在格式化資源上;display 使用在顯示選單和對話框中。新的 getDefault(Locale.Category)
方法可傳入 Locale.Category
參數。傳入 FORMAT
列舉的話,則此方法會回傳可供格式化資源的預設地區。同樣地,傳入 DISPLAY
列舉的話則會回傳 UI 所使用的預設地區。setDefault(Locale.Category, Locale)
方法可用為指定的分類設定地區。無參數的 getDefault()
方法會回傳 DISPLAY
的預設值。
在 Microsoft Windows 上,預設的初始值會依據 Windows 控制台中的「標準及格式」和「顯示語言」設定。
Locale
類別支援 BCP47 和 UTR35
Locale
類別已更新實作 BCP 47(IETF BCP 47, “Tags for Identifying Languages”)和與 BCP 47 相容的 LDML(UTR#35, “Unicode Local Data Markup Language”)延伸以作為地區資料交換。
下述的巢狀類別已在本版中加入 Locale
類別:
Locale.Builder
可以用來建立Locale
實體,並且可利用 setter 方法來修改其設定值。
下列方法已加入 Locale
類別:
getExtensionKeys()
getExtension(char)
getUnicodeLocaleType(String)
getUnicodeLocaleKeys()
getUnicodeLocaleAttributes()
forLanguageTag(String)
toLanguageTag()
getScript()
getDisplayScript()
getDisplayScript(Locale)
下列常數已加入 Locale
類別:
更多訊息請參考 Java Tutorials 中的建立一個 Locale
以及 BCP 47 延伸。
新的 NumericShaper
方法
NumericShaper
類別用來轉換 Latin-1(歐洲語系)數字到其他的 Unicode 十進位數字。在 Java SE 7 中加入了 NumericShaper.Range
列舉,用來表達擁有十進位數字的字元集其 Unicode 的範圍。下列使用了 NumericShaper.Range
列舉的方法也一併加入了 Java SE 7 之中:
getShaper(NumericShaper.Range)
:為指定的 Unicode 範圍傳回相應NumericShaper
物件getContextualShaper(Set)
:為指定的 Unicode 範圍集合傳回與環境相關的NumericShaper
物件。此物件假定歐洲語系為起啟環境。getContextualShaper(Set NumericShaper.Range)
:為指定的 Unicode 範圍集合傳回與環境相關的NumericShaper
物件。此物件使用defaultContext
做為起啟環境。shape(char[], int start, int count, NumericShaper.Range)
:使用所提供的環境,轉換出現在 start 到 start + count 之間的數字。
更多資訊請參考 Java Tutorials 中的轉換拉丁數字到其他 Unicode 數字。
正規表示法(Regular Expression)API 支援 Unicode 6.0
正規表示法模式已擴展為可支援 Unicode 6.0 匹配。你可以用 \\u 或 \\x 跳脫序列去匹配 Unicode 文字集(code points)。
Java Tutorials 中的 Unicode 支援頁面有更多的資訊。
java.lang
套件
- Java SE 7 中多執行緒的客製類別載入器:多執行緒和非階層式委任的客製化類別載入器已經消除潛在的死結。
Java 程式語言
二進位數字表示法
在 Java SE 7 中,整數型態(byte
、short
、int
以及 long
)可表達成二進位數字系統,用 0b
或 0B
開頭來指定二進位數字。
數值文字中的底線
在數值文字中,底線可以出現在所有數字之間。舉例來說,這項功能可以讓你在數值文字中去區分數字組,藉此增進程式碼的可讀性。
switch
指令支援字串
你可以在 switch
指令中使用 String
類別了。
泛型實體創建時的型別推論
現在可以用一個空的型別參數集(<>
)來取代之前呼叫泛型類別的建構子時所需傳入的型別引數了,只要編譯器能從上下文中推斷該用哪些型別引數。此一角括號對被非正式地稱之為 diamond。
改進了編譯器警告和錯誤訊息:在 Varargs 方法中無法實體化其形式參數時
當程式中無法實體化形式參數(formal parameter)時,Java SE7 編譯器會在該可變長度引數的方法和建樣子的宣告處發出警告訊息。Java SE 7 導入編譯器選項 -Xlint:varargs
和標註 @SafeVarargs
以及 @SuppressWarnings({"unchecked", "varargs"})
來抑制這些警告。
try
-with-resources 指令
此指令為宣告了一個或多個資源的 try
指令。resource 指的是在程式區段結束後必須被關閉的物件。try
-with-resources 指令可確保每項資源在指令的最後都會被關閉。所有實作了 java.lang.AutoCloseable
介面和 java.lang.Closeable
介面的物件皆可視為 resource。java.io.InputStream
、OutputStream
、Reader
、Writer
、java.sql.Connection
、Statement
以及 ResultSet
都已翻新並實作 java.lang.AutoCloseable
介面,並且可以在 try
-with-resources 指令中使用。
抓取多種例外型別並以改進過的型別檢查來重新拋出例外
單一的 catch
區段可以處理超過一種以上的例外型別。另外和早期版本比較起來,編譯器可以更精確的分析需重新拋出的例外型別。這可以讓你在方法宣告的 throws
子句中可指定更多明確的例外型別。
Java 虛擬機器
- JVM 支援非 Java 的語言:Java SE 7 導入了新的 JVM 指令(
invokedynamic
),可簡化 JVM 中動態類型語言的實作方式。 - 垃圾優先的垃圾收集器:這是用來取代 Concurrent Mark-Sweep Collector(CMS)的伺服器式垃圾收集器。
- Java HotSpot 虛擬機器效能提升
JDBC
JDBC 4.1 加入了下列功能:
- 可以用
try
-with-resources 指令去自動關閉Connection
、Statement
以及ResultSet
型別的資源。請參見處理 SQL 述句中的關閉連線。 - RowSet 1.1:加入
RowSetFactory
介面和RowSetProvider
類別,可讓你去建立所有被你的 JDBC 驅動程式所支援的 row set 類型。請參見使用 JdbcRowSet 物件中的使用 RowSetFactory 介面建立。