JDK8 Optional類

JDK8 Optional類

做爲JDK8新特性之一,Optinal這個容器類,在工做中常常用到,也是很是好用的一個類,讓你的判斷空變得優雅;java

首先來看看官方在Optional類上的註釋數據庫

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. 一個有可能包含一個非空值的容器,若是該值不爲空(isPresent方法能夠判斷),將經過get()方法返回該值ide

Additional methods that depend on the presence or absence of a contained value are provided, such as {@linkorElse(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).另外容器提供了額外的方法用於處理容器內的值存在或者不存在的狀況,例如orElse()spa

蹩腳的英文翻譯完畢,下面描述下Optional的類做用:翻譯

1.能夠用於解決因爲返回值爲null致使的NullPointException問題;
2.將非空判斷的方式''標準化''
複製代碼

廢話很少說,下面上代碼:指針

代碼原型-案例摘自<<Java8實戰>>code

public class Person {
    private Car car;
    public Car getCar() { return car; }
}
public class Car {
    private Insurance insurance;
    public Insurance getInsurance() { return insurance; }
}
public class Insurance {
    private String name;
    public String getName() { return name; }
}
//那麼,下面這段代碼存在怎樣的問題呢?
public String getCarInsuranceName(Person person) {
    return person.getCar().getInsurance().getName();
}
複製代碼

顯然在上述代碼的對象

getCarInsuranceName(Personperson)
複製代碼

方法中,因爲person是否爲null不肯定性,有可能致使person在調用getCar()致使NullPointerException的發生,亦或因爲getCar()方法的值爲null,以及getInsurance()方法爲null致使的方法調用出現NullPointerException的問題ci

傳統的解決方式:

1.過多的判斷 例如開發

public String getCarInsuranceName(Person person) {
    if (person != null) {
        Car car = person.getCar();
        if (car != null) {
            Insurance insurance = car.getInsurance();
                if (insurance != null) {
                    return insurance.getName();
                    }
                }
            }
        return "Unknown";
    }
複製代碼

2.過多的退出語句

public String getCarInsuranceName(Person person) {
    if (person == null) {
        return "Unknown";
    }
    Car car = person.getCar();
    if (car == null) {
        return "Unknown";
    }
    Insurance insurance = car.getInsurance();
    if (insurance == null) {
        return "Unknown";
    }
    return insurance.getName();
}
複製代碼

以上兩種解決方式是否是特色繁瑣,明明一樣的工做,卻反覆作了三次,代碼的可讀性變差,你願意寫這樣的代碼嗎?這個時候Optional類登場了 那麼使用Optional類以後的作法是:

public String getCarInsuranceName(Person person) {
    Optional.ofNullable(person).flatMap(Person::getCar).flatMap(Car::getInsurance).map(Insurance::getName).orElse("unKnown")
}
複製代碼

在上述改造中Optional.ofNullable()方法將傳入的參數person包裝了一番,即容許person爲空,此時看看該方法的源碼

Returns an {@code Optional} describing the specified value, if non-null, otherwise returns an empty {@code Optional}.返回該容器內的非空值的容器對象,若爲空,則返回調用empty()方法返回null值對應的容器對象

public static <T> Optional<T> ofNullable(T value) {
   return value == null ? empty() : of(value);
}
複製代碼

該方法返回一個Optional類容器對象,而後在獲取getCar(),getInsurance(),getName()的方法中若是任一方法返回值爲null,那麼就將返回unKnown這個值,巧妙的避免了null值調用,而是用容器對象調用;

例子結束,那麼咱們再看看Optional類中其餘實用的方法

1. get()方法
public T get() {
       if (value == null) {
           throw new NoSuchElementException("No value present");
       }
       return value;
   }
複製代碼

get()方法用於獲取容器內的value值,在value值不存在的時候將會報出異常,那麼這時候有個問題了,依前述所言,Optional類不該該是解決null值問題的嗎,怎麼會容許這種狀況發生呢?咱們繼續看第二個方法isPersent()

2.isPersent()
public boolean isPresent() {
       return value != null;
   }
複製代碼

isPersent()方法用於判斷容器內是的值是否爲null,返回值爲Boolean類型, 一般的作法爲isPresent()和get()方法連用

private String test() {
       String name="null or not null?";
       Optional<String> optional = Optional.of(name);
       if (optional.isPresent()){
           throw  new RuntimeException("結果異常");
       }
       return  optional.get();
   }
複製代碼

這種作法在實際開發中中,dao層查詢數據庫返回結果給service層時經常使用該方法;

3.orElse()
Person person = userService.findById(5);
   return  Optional.ofNullable(person).filter(p->p.getAge()>0).orElse(new Person(0,"default"));
複製代碼

過濾查詢結果的age屬性大於0的對象,此時這裏雖然沒有作null值判斷,可是ofNullable()方法會自動進行處理,從而不會致使空指針問題

相關文章
相關標籤/搜索