
Java 教程
- Java - 首頁
- Java - 概述
- Java - 歷史
- Java - 特性
- Java 與 C++
- JVM - Java 虛擬機器
- Java - JDK、JRE 和 JVM 的區別
- Java - Hello World 程式
- Java - 環境搭建
- Java - 基本語法
- Java - 變數型別
- Java - 資料型別
- Java - 型別轉換
- Java - Unicode 系統
- Java - 基本運算子
- Java - 註釋
- Java - 使用者輸入
- Java - 日期和時間
Java 控制語句
- Java - 迴圈控制
- Java - 決策制定
- Java - if-else
- Java - switch
- Java - for 迴圈
- Java - for-each 迴圈
- Java - while 迴圈
- Java - do-while 迴圈
- Java - break
- Java - continue
面向物件程式設計
- Java - 面向物件程式設計概念
- Java - 物件和類
- Java - 類屬性
- Java - 類方法
- Java - 方法
- Java - 變數作用域
- Java - 建構函式
- Java - 訪問修飾符
- Java - 繼承
- Java - 聚合
- Java - 多型
- Java - 重寫
- Java - 方法過載
- Java - 動態繫結
- Java - 靜態繫結
- Java - 例項初始化塊
- Java - 抽象
- Java - 封裝
- Java - 介面
- Java - 包
- Java - 內部類
- Java - 靜態類
- Java - 匿名類
- Java - 單例類
- Java - 包裝類
- Java - 列舉
- Java - 列舉建構函式
- Java - 列舉字串
Java 內建類
Java 檔案處理
Java 錯誤和異常
- Java - 異常
- Java - try-catch 塊
- Java - try-with-resources
- Java - 多 catch 塊
- Java - 巢狀 try 塊
- Java - finally 塊
- Java - throw 異常
- Java - 異常傳播
- Java - 內建異常
- Java - 自定義異常
Java 多執行緒
- Java - 多執行緒
- Java - 執行緒生命週期
- Java - 建立執行緒
- Java - 啟動執行緒
- Java - 加入執行緒
- Java - 執行緒命名
- Java - 執行緒排程器
- Java - 執行緒池
- Java - 主執行緒
- Java - 執行緒優先順序
- Java - 守護執行緒
- Java - 執行緒組
- Java - 關閉鉤子
Java 同步
Java 網路程式設計
- Java - 網路程式設計
- Java - 套接字程式設計
- Java - URL 處理
- Java - URL 類
- Java - URLConnection 類
- Java - HttpURLConnection 類
- Java - Socket 類
- Java - 泛型
Java 集合
Java 介面
Java 資料結構
Java 集合演算法
高階 Java
- Java - 命令列引數
- Java - Lambda 表示式
- Java - 傳送郵件
- Java - Applet 基礎
- Java - Javadoc 註釋
- Java - 自動裝箱和拆箱
- Java - 檔案不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 檔案
- Java - 私有介面方法
- Java - 內部類菱形運算子
- Java - 多解析度影像 API
- Java - 集合工廠方法
- Java - 模組系統
- Java - Nashorn JavaScript
- Java - Optional 類
- Java - 方法引用
- Java - 函式式介面
- Java - 預設方法
- Java - Base64 編碼解碼
- Java - switch 表示式
- Java - Teeing 收集器
- Java - 微基準測試
- Java - 文字塊
- Java - 動態 CDS 歸檔
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指標異常
- Java - 打包工具
- Java - 密封類
- Java - 記錄類
- Java - 隱藏類
- Java - 模式匹配
- Java - 簡潔的數字格式化
- Java - 垃圾回收
- Java - JIT 編譯器
Java 雜項
- Java - 遞迴
- Java - 正則表示式
- Java - 序列化
- Java - 字串
- Java - Process API改進
- Java - Stream API改進
- Java - 增強的@Deprecated 註解
- Java - CompletableFuture API改進
- Java - 流
- Java - 日期時間 API
- Java 8 新特性
- Java 9 新特性
- Java 10 新特性
- Java 11 新特性
- Java 12 新特性
- Java 13 新特性
- Java 14 新特性
- Java 15 新特性
- Java 16 新特性
Java API 和框架
Java 類引用
- Java - Scanner
- Java - 陣列
- Java - 字串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java 有用資源
Java 8 新特性
JAVA 8 是 JAVA 程式語言 開發的一個主要功能版本。其初始版本於 2014 年 3 月 18 日釋出。隨著 Java 8 的釋出,Java 提供了對函數語言程式設計、新的 JavaScript 引擎、新的日期時間操作 API、新的流 API 等的支援。
以下是 Java 8 支援的新特性列表:
Lambda 表示式
Lambda 表示式 是 Java 中引入的最重要的特性之一。Lambda 表示式促進了 Java 中的函數語言程式設計。Lambda 表示式基於函式式介面的原理。函式式介面是一個只有一個方法要實現的介面。Lambda 表示式提供函式式介面方法的實現。
Lambda 表示式極大地簡化了函數語言程式設計,並使程式碼更易讀,無需任何樣板程式碼。Lambda 表示式可以推斷使用的引數型別,並且可以在沒有 return 關鍵字的情況下返回值。對於簡單的單語句方法,甚至可以省略大括號。
示例 - 使用 Lambda 表示式
以下示例展示了 Lambda 表示式的用法。Lambda 表示式最適合與函式式介面一起使用,函式式介面只有一個抽象方法。我們定義了一個只有一個方法 operate 的介面 Calculator,它可以接受兩個引數並返回一個值。在 main 方法中,我們首先使用匿名函式實現了 Calculator 介面,然後使用 Lambda 表示式。operate() 方法在兩種情況下都被呼叫以列印結果,並且結果都被打印出來。
package com.tutorialspoint; public class Tester { public static void main(String[] args) { // Interface implementation using anonymous class Calculator sum = new Calculator() { @Override public int operate(int a, int b) { return a + b; } }; int result = sum.operate(2,3); System.out.println(result); // Interface implementation using lambda expression Calculator sum1 = (a,b) -> a + b; result = sum1.operate(2,3); System.out.println(result); } interface Calculator { int operate(int a, int b); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
5 5
方法引用
方法引用 是一種簡短而簡潔的呼叫方法、靜態方法甚至建構函式的方式,無需冗長的語法。方法引用有助於透過名稱指向方法,即使不指定引數也是如此。引數由 Lambda 表示式傳遞。方法引用使用 "::" 符號描述。
可以使用以下語法引用靜態方法:
<<class-name>>::methodName
可以使用以下語法引用例項方法:
<<object-name>>::methodName
可以使用以下語法呼叫建構函式:
<<class-name>>::new
示例 - 使用方法引用
在這個例子中,我們使用了靜態方法 compare 和例項方法 compareTo 來排序兩個整數的 ArrayList。我們使用方法引用來表示靜態方法和例項方法。
package com.tutorialspoint; import java.util.Arrays; import java.util.List; public class Tester { public static void main(String args[]) { List<Integer> numbers = Arrays.asList(1,2,4,9,8,7,3); System.out.println("Sorted using static method reference"); // Use static method compare numbers = numbers.stream().sorted(Integer::compare).toList(); System.out.println(numbers); numbers = Arrays.asList(1,2,4,9,8,7,3); System.out.println("Sorted using instance method reference" ); // Use instance method compareTo numbers = numbers.stream().sorted(Integer::compareTo).toList(); System.out.println(numbers); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
Sorted using static method reference [1, 2, 3, 4, 7, 8, 9] Sorted using instance method reference [1, 2, 3, 4, 7, 8, 9]
預設方法
在 Java 8 之前,介面只能包含抽象方法。隨著 Java 8 的釋出,引入了 Lambda 表示式。現在為了向後相容性,添加了 預設方法 功能,以便舊的 介面 可以利用 Lambda 表示式而無需修改其實現。
例如,List 或 Collection 介面 沒有 'forEach' 方法宣告。因此,新增此方法只會破壞集合框架的實現。Java 8 引入了預設方法,以便 List/Collection 介面可以具有 forEach 方法的預設實現,而實現這些介面的類無需實現相同的方法。
語法
以下是 Java 中介面中預設方法的語法:
public interface vehicle { default void message() { System.out.println("I am a vehicle!"); } }
示例 - 使用預設方法
在這個例子中,我們建立了一個包含預設方法的介面。在實現類中,此訊息未實現,用於列印訊息。
package com.tutorialspoint; interface vehicle { // default method must have an implementation default void message() { System.out.println("I am a vehicle!"); } } // implementing class need not to implement the default method // of an interface. public class Tester implements vehicle { public static void main(String args[]) { Tester tester = new Tester(); // implementing class can access the default method as its own method tester.message(); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
I am a vehicle!
Stream API
Stream API 是 Java 8 中引入的一個新的抽象層,用於以宣告式方式處理資料。流表示一系列元素。流以順序方式提供特定型別的元素集合。流按需獲取/計算元素。它永遠不會儲存元素。
Stream 支援聚合操作,例如 filter、map、limit、reduce、find、match 等,並且可以在內部對提供的源元素進行迭代,這與需要顯式迭代的集合形成對比。
語法
以下是使用流的通用語法
<<collection-instance>>.stream().<<non-terminal-operation()>>.<<non-terminal-operation()>>.<<terminal-operation()>>
示例 - 使用 Stream
在這個例子中,我們建立了一個字串列表,其中一些條目為空。現在使用 Stream API,我們過濾空字串並計算它們的數量。
package com.tutorialspoint; import java.util.Arrays; import java.util.List; public class Tester { public static void main(String args[]) { List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // get stream from list using stream() method // then apply filter // lastly count the result of filter long count = strings.stream().filter(string->string.isEmpty()).count(); System.out.println("Empty Strings: " + count); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
Empty Strings: 2
Optional 類
Optional 類 功能是在 Java 8 中引入的,用於以程式設計方式處理空指標異常場景,使程式更簡潔、更不易出錯。當使用空物件引用獲取其值或呼叫其方法時,就會發生空指標異常。隨著程式規模的增加,處理所有可能發生空指標異常的情況變得非常繁瑣。
Optional 類例項為物件提供了一個包裝器,其中包含許多實用程式方法,例如在底層值為 null 時獲取備用值,檢查物件引用是否為 null 等。
示例 - 使用 Optional 類
在這個例子中,我們使用 oofNullable() 方法建立了兩個 Optional 類例項,該方法允許將底層物件作為 null 傳遞,然後使用 orElse() 方法檢索值,如果底層物件為 null,則返回預設值。
package com.tutorialspoint; import java.util.Optional; public class Tester { public static void main(String args[]) { // case 1: Optional is having null as underlying value Optional<Integer> valueOptional = Optional.ofNullable(null); // case 2: Optional is having not null as underlying value Optional<Integer> valueOptional1 = Optional.ofNullable(Integer.valueOf(10)); // orElse will return -1 being default value Integer value = valueOptional.orElse(Integer.valueOf(-1)); System.out.println(value); // orElse will return the underlying value Integer value1 = valueOptional1.orElse(Integer.valueOf(-1)); System.out.println(value1); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
-1 10
新的日期時間 API
Java 8 引入了一個新的日期時間 API,它是執行緒安全的,支援時區,並具有多個直接處理日期操作的方法。早期的日期時間 API 不是執行緒安全的,在併發問題中,在使用日期時可能會出現問題。新的日期時間 API 使用不可變結構,沒有 setter 方法,因此使 API 更安全。新的 API 在設計時考慮了時區和特定領域的需要。
Java 8 在 java.time 包下引入了一個新的日期時間 API。以下是 java.time 包中引入的一些重要類。
Local − 簡化的日期時間 API,沒有時區處理的複雜性。
Zoned − 用於處理各種時區的專用日期時間 API。
示例 - 使用日期時間 API
在這個例子中,我們使用 oofNullable() 方法建立了兩個 Optional 類例項,該方法允許將底層物件作為 null 傳遞,然後使用 orElse() 方法檢索值,如果底層物件為 null,則返回預設值。
package com.tutorialspoint; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; import java.time.ZonedDateTime; public class Tester { public static void main(String args[]) { // Get the current date and time LocalDateTime currentTime = LocalDateTime.now(); System.out.println("Current DateTime: " + currentTime); LocalDate date1 = currentTime.toLocalDate(); System.out.println("date1: " + date1); Month month = currentTime.getMonth(); int day = currentTime.getDayOfMonth(); int seconds = currentTime.getSecond(); System.out.println("Month: " + month +", day: " + day +", seconds: " + seconds); ZonedDateTime date2 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]"); System.out.println("date2: " + date2); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
Current DateTime: 2024-03-07T10:29:15.650806 date1: 2024-03-07 Month: MARCH, day: 7, seconds: 15 date2: 2007-12-03T09:45:30+05:00[Asia/Karachi]
Nashorn JavaScript 引擎
Nashorn 是一個非常強大且高效的 Javascript 引擎,它作為現有 javascript 引擎 Rhino 的替代品而引入。Nashorn 引擎號稱速度是 Rhino 的 2 到 10 倍,因為它可以直接將 JavaScript 程式碼編譯為位元組碼。Nashorn 引擎允許在 Java 檔案中執行執行 JavaScript 程式碼,我們甚至可以在 JavaScript 程式碼片段中執行 Java 程式碼。使用 Nashorn 引擎,引入了命令列工具 jjs 來在命令列工具中執行 javascript。
直接在命令提示符中執行 JavaScript
開啟控制檯,鍵入 jjs 並按 Enter 鍵。jjs 工具將開啟一個互動式會話。jjs 會話開啟後,我們可以執行 javascript 程式碼。完成後,鍵入quit() 並按 Enter 鍵退出 jjs 互動式會話並返回到命令提示符。
示例
C:\JAVA>jjs jjs> print("Hello, World!") Hello, World! jjs> quit() >> C:\JAVA>
示例 - 在 Java 程式碼中使用 Javascript 程式碼
自 Java 6 以來,Java 就有一個 ScriptEngineManager 類,本例中使用它將 javascript 引擎載入為 ScriptEngine 例項。一旦引擎載入到 java 程式碼中,我們就可以呼叫eval() 方法來評估 Java 中的 JavaScript 程式碼。我們甚至可以在 javascript 程式碼片段中使用Java 變數。
package com.tutorialspoint; import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; import javax.script.ScriptException; public class Tester { public static void main(String args[]) { // create the script engine manager ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); // load the Nashorn javascript engine ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn"); String message = "This is a message"; String expression = "10 + 2"; Integer result = null; try { // call the javascript function, pass a java variable nashorn.eval("print('" + message + "')"); // call the javascript function and get the result back in java result = (Integer) nashorn.eval(expression); } catch(ScriptException e) { System.out.println("Error executing script: "+ e.getMessage()); } System.out.println(result.toString()); } }
讓我們編譯並執行上面的程式,這將產生以下結果:
This is a message 12
Nashorn 引擎在 Java 11 中已棄用,在 Java 15 中已刪除,並由 GraalVM javascript 引擎取代。