Java8新特性——Optional類
前言
Java 8中引入了一個(gè)新的Optional類,它可以讓開(kāi)發(fā)人員更好地處理可能為空的值。Optional類提供了一種方式,可以更加優(yōu)雅地處理null值,并在運(yùn)行時(shí)避免NullPointerException異常的出現(xiàn)。本文將介紹Optional類的基本語(yǔ)法、使用場(chǎng)景和示例。
基本語(yǔ)法
Optional類是一個(gè)泛型類,可以包含任何類型的值。Optional類有兩個(gè)靜態(tài)方法:of()和empty()。of()方法用于創(chuàng)建一個(gè)包含非空值的Optional對(duì)象,如果傳入的值為null,則會(huì)拋出NullPointerException異常。而empty()方法則用于創(chuàng)建一個(gè)空的Optional對(duì)象。
Optional類還提供了一些方法,用于判斷Optional對(duì)象是否為空、獲取Optional對(duì)象中的值等。例如,isPresent()方法用于判斷Optional對(duì)象是否為空,如果Optional對(duì)象包含值,則返回true;否則返回false。get()方法用于獲取Optional對(duì)象中的值,如果Optional對(duì)象為空,則會(huì)拋出NoSuchElementException異常。
Optional類還提供了一些其他方法,如map()、flatMap()、orElse()、orElseGet()、orElseThrow()等,這些方法可以讓開(kāi)發(fā)人員更加靈活地處理Optional對(duì)象中的值。

使用場(chǎng)景
Optional類適用于任何可能返回null值的情況。例如,在處理集合或數(shù)組時(shí),可能會(huì)出現(xiàn)null值,使用Optional類可以更好地處理這種情況。在使用第三方庫(kù)時(shí),可能會(huì)返回null值,此時(shí)使用Optional類可以避免NullPointerException異常的出現(xiàn)。在編寫(xiě)公共API時(shí),使用Optional類可以更好地指導(dǎo)開(kāi)發(fā)人員如何處理可能為空的值。
使用示例
下面是一個(gè)示例,展示了如何使用Optional類來(lái)避免NullPointerException異常的出現(xiàn):
public class Person {
? ?private String name;
? ?private Integer age;
? ?public Person(String name, Integer age) {
? ? ? ?this.name = name;
? ? ? ?this.age = age;
? ?}
? ?public Optional<String> getName() {
? ? ? ?return Optional.ofNullable(name);
? ?}
? ?public Optional<Integer> getAge() {
? ? ? ?return Optional.ofNullable(age);
? ?}
? ?public static void main(String[] args) {
? ? ? ?Person person1 = new Person("Tom", 20);
? ? ? ?Person person2 = new Person(null, 25);
? ? ? ?String name1 = person1.getName().orElse("Unknown");
? ? ? ?String name2 = person2.getName().orElse("Unknown");
? ? ? ?Integer age1 = person1.getAge().orElseThrow(() -> new RuntimeException("Age is missing."));
? ? ? ?Integer age2 = person2.getAge().orElseThrow(() -> new RuntimeException("Age is missing."));
? ? ? ?System.out.println("Person 1: " + name1 + ", " + age1);
? ? ? ?System.out.println("Person 2: " + name2 + ", " + age2);
? ?}
}
在上面的示例中,Person類包含一個(gè)name字段和一個(gè)age字段。getName()方法和getAge()方法返回的都是Optional對(duì)象。在main()方法中,我們創(chuàng)建了兩個(gè)Person對(duì)象,一個(gè)包含name和age字段,另一個(gè)只包含age字段。我們使用orElse()方法獲取name字段的值,如果name字段為null,則返回"Unknown"。我們還使用orElseThrow()方法獲取age字段的值,如果age字段為null,則拋出RuntimeException異常。
運(yùn)行上述代碼,可以得到如下輸出:
Person 1: Tom, 20
Person 2: Unknown, 25
Exception in thread "main" java.lang.RuntimeException: Age is missing.
? ?at Person.main(Person.java:23)
從輸出可以看出,使用Optional類可以更加優(yōu)雅地處理null值,并在運(yùn)行時(shí)避免NullPointerException異常的出現(xiàn)。
除了使用orElse()和orElseThrow()方法來(lái)獲取Optional對(duì)象中的值之外,我們還可以使用map()和flatMap()方法來(lái)對(duì)Optional對(duì)象中的值進(jìn)行操作。例如,假設(shè)我們需要對(duì)一個(gè)Optional對(duì)象中的字符串進(jìn)行大寫(xiě)轉(zhuǎn)換,我們可以使用map()方法來(lái)實(shí)現(xiàn):
Optional<String> optional = Optional.of("hello");
optional = optional.map(s -> s.toUpperCase());
System.out.println(optional.get()); // 輸出"HELLO"
在上述示例中,我們使用of()方法創(chuàng)建了一個(gè)包含字符串"hello"的Optional對(duì)象。然后使用map()方法對(duì)字符串進(jìn)行了大寫(xiě)轉(zhuǎn)換。最后使用get()方法獲取了轉(zhuǎn)換后的字符串值。
除了map()方法之外,我們還可以使用flatMap()方法來(lái)對(duì)Optional對(duì)象進(jìn)行操作。例如,假設(shè)我們有一個(gè)Optional對(duì)象,其中包含一個(gè)字符串,我們需要將這個(gè)字符串轉(zhuǎn)換為一個(gè)包含多個(gè)字符的字符串列表,我們可以使用flatMap()方法來(lái)實(shí)現(xiàn):
Optional<String> optional = Optional.of("hello");
List<String> list = optional.flatMap(s -> Optional.ofNullable(s.split(""))).map(Arrays::asList).orElse(Collections.emptyList());
System.out.println(list); // 輸出"[h, e, l, l, o]"
在上述示例中,我們使用of()方法創(chuàng)建了一個(gè)包含字符串"hello"的Optional對(duì)象。然后使用flatMap()方法將字符串拆分成字符數(shù)組,并將字符數(shù)組轉(zhuǎn)換為一個(gè)Optional對(duì)象。接著使用map()方法將字符數(shù)組轉(zhuǎn)換為一個(gè)字符串列表。最后使用orElse()方法獲取了轉(zhuǎn)換后的字符串列表值。