(原)
先看看上面的說明:
/**
* A container object which may or may not contain a non-null value.
* If a value is present, {@code isPresent()} will return {@code true} and
* {@code get()} will return the value.
*Optional是一個容器對象,它可能包含,也可能不包含一個非空的值,如果這個值存在,isPresent方法將返回true,get方法將會返回它本身
* <p>Additional methods that depend on the presence or absence of a contained
* value are provided, such as {@link #orElse(java.lang.Object) orElse()}
* (return a default value if value not present) and
* {@link #ifPresent(java.util.function.Consumer) ifPresent()} (execute a block
* of code if the value is present).
*Optional提供一些額外的方法,這些方法依賴於它所包含的對象存在與否,例如orElse如果這個包含的對象不存在,將會返回一個默認值和ifPresent方法,如果包含的值存在,則會執行方法塊中的內容
* <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
* class; use of identity-sensitive operations (including reference equality
* ({@code ==}), hash code, or synchronization) on instances of
* {@code Optional} may have unpredictable results and should be avoided.
*這是一個基於值的class類,對於同一性(特性)敏感的操作 (包含引用的相等性如:==),同一性的hashcode或者同步等等、對optional實例可能會產生不可預料的結果,這種結果應該被避免。
* @since 1.8
*/
再看看該類:
public final class Optional<T>
這里一個final類
這是一個基於值的類,上面給出了什么叫基於值,上面給出的鏈接地址不全,看這里:
http://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html

這里說的是基於值的類需要滿足以下幾點:
1、 final類型和不可變的(可能會包含可變對象的引用)
2、 有equals、hashCode、toString方法的實現,它是通過實例的狀態計算出來的,而並不會通過其它的對象或變量去計算。
3、 不會使用身份敏感的操作,比如在二個實例之間引用相等性、hashCode或者內在的鎖。
4、 判斷二個值相等僅僅通過equal方法,而不會通過==去判斷。
5、 它不提供構造方法,它通過工廠方法創建它的實例,這不保證返回實例的一致性。
6、 當它們相等時,它是可以自由替換的。如果x和y 調用equal方法返回true,那么可以將x和y任意交換,它的結果不會產生任何變化。
然后再回來看Optional,你能看到它是私有的:
private Optional() {
this.value = null;
}

在它的所有方法中,如果要創建Optional對象,先看看它常用的三個方法。
empty方法回一個空的 Optional對象。
of方法接收一個T參數,T必需為非null值,返回一個Optional對象。
ofNullable方法接收一個T參數,如果T為null,它會調用empty方法,如果不為null則調用of方法。
再看看這二個方法:
isPresent: 如果這個對象的值不為null返回true,否則返回false。
get:如果這個值存在,則返回這個值,如果這個值為null,則拋出異常。
在使用中,這二個方法基本是成對出現的,下面來看一個例子。
String str = "hello";
Optional<String> strValue = Optional.of(str);
System.out.println("part1-------------------");
if(str != null){
System.out.println(str);
}
System.out.println("part2-------------------");
if(strValue.isPresent()){
System.out.println(strValue.get());
}
這里,part1和part2的代碼是等價的,Optional還提供了一種更簡單的方法
strValue.ifPresent(s -> System.out.println(s));
ifPresent方法接收一個consumer函數式接口(之前介紹過),將自己的非空的邏輯寫進去。Optioanal該方法更加簡潔。
orElse方法:接收一個參數,如果存在,返回這個值本身,否則返回返回這個參數。
orElseGet方法:接收一個Supplier,如果存在,返回這個值本身,否則返回Supplier
對象。
map方法:接收一個Function,如果Optioanal為null則拋出異常(所以這里創建Optional對象時建議用Optional.ofNullable()),如果為空值則返回空,如果不為空則返回Function的返回值。
(例如:一個對象Obj,有一個List屬性,如果List有值,返回List,否則返回空集合,可以這么寫(
Parent parent = new Parent(); Optional<Parent> parentVal = Optional.ofNullable(parent); System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));
)
Optioanal通常作為方法的返回值來使用,它可以有效的規避返回null的結果,如果一個類需要序列化,當Optional作為參數類型或是成員變量類型是有問題的。因為Optional沒有實現序列化,所以Optioanl通常不被建議作為參數或常量使用。
下面給出一些Optional常用的例子:
package com.demo.jdk8;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class Test6 {
public static void main(String[] args) {
String str = "hello";
Optional<String> strValue = Optional.of(str);
System.out.println("part1-------------------");
if(str != null){
System.out.println(str);
}
System.out.println("part2-------------------");
if(strValue.isPresent()){
System.out.println(strValue.get());
}
System.out.println("part3-------------------");
strValue.ifPresent(s -> System.out.println(s));
System.out.println("part4-------------------");
Optional<String> op = Optional.ofNullable(null);
System.out.println(op.orElse("hahahaha"));
System.out.println("part5-------------------");
Optional<String> opt = Optional.ofNullable("nihao");
System.out.println(op.orElseGet(() -> "hehehe"));
System.out.println("part6-------------------");
System.out.println(opt.map(m -> m + "123").orElseGet(() -> "world"));
System.out.println("part7-------------------");
Parent parent = new Parent();
// List<Object> list = Arrays.asList("張三","李四");
// parent.setList(list);
Optional<Parent> parentVal = Optional.ofNullable(parent);
System.out.println(parentVal.map(m -> m.getList()).orElse(Collections.emptyList()));
}
public void test(Optional optional){
}
}
class Parent{
private List<Object> list;
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
}
例子請看這里:https://github.com/LeeScofield/java8
