1、前言
相信不少小伙伴已經被java的NPE(Null Pointer Exception
)所謂的空指針異常搞的頭昏腦漲,有大佬說過“防止 NPE,是程序員的基本修養。”但是修養歸修養,也是我們程序員最頭疼的問題之一,那么我們今天就要盡可能的利用Java8的新特性 Optional
來盡量簡化代碼同時高效處理NPE(Null Pointer Exception
空指針異常)
2、認識Optional并使用
簡單來說,Opitonal類就是Java提供的為了解決大家平時判斷對象是否為空用 會用 null!=obj 這樣的方式存在的判斷,從而令人頭疼導致NPE(Null Pointer Exception
空指針異常),同時Optional的存在可以讓代碼更加簡單,可讀性跟高,代碼寫起來更高效.
常規判斷:
//對象人
//屬性有name,age
Personperson=newPerson();
if(null==person){
return"person為null";
}
returnperson;
使用Optional:
//對象人
//屬性有name,age
Personperson=newPerson();
returnOptional.ofNullable(person).orElse("person為null");
測試展示類Person代碼(如果有朋友不明白可以看一下這個):
publicclassPerson{
privateStringname;
privateIntegerage;
publicPerson(Stringname,Integerage){
this.name=name;
this.age=age;
}
publicPerson(){
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
}
下面,我們就高效的學習一下神奇的Optional類!
2.1 Optional對象創建
首先我們先打開Optional的內部,去一探究竟 先把幾個創建Optional對象的方法提取出來
publicfinalclassOptional<T>{
privatestaticfinalOptionalEMPTY=newOptional<>();
privatefinalTvalue;
//我們可以看到兩個構造方格都是private私有的
//說明我們沒辦法在外面去new出來Optional對象
privateOptional(){
this.value=null;
}
privateOptional(Tvalue){
this.value=Objects.requireNonNull(value);
}
//這個靜態方法大致是創建出一個包裝值為空的一個對象因為沒有任何參數賦值
publicstaticOptionalempty(){
@SuppressWarnings("unchecked")
Optionalt=(Optional)EMPTY;
returnt;
}
//這個靜態方法大致是創建出一個包裝值非空的一個對象因為做了賦值
publicstaticOptionalof(Tvalue){
returnnewOptional<>(value);
}
//這個靜態方法大致是如果參數value為空,則創建空對象,如果不為空,則創建有參對象
publicstaticOptionalofNullable(Tvalue){
returnvalue==null?empty():of(value);
}
}
再做一個簡單的實例展示 與上面對應
//1、創建一個包裝對象值為空的Optional對象
OptionaloptEmpty=Optional.empty();
//2、創建包裝對象值非空的Optional對象
OptionaloptOf=Optional.of("optional");
//3、創建包裝對象值允許為空也可以不為空的Optional對象
OptionaloptOfNullable1=Optional.ofNullable(null);
OptionaloptOfNullable2=Optional.ofNullable("optional");
我們關于創建Optional對象的內部方法大致分析完畢 接下來也正式的進入Optional的學習與使用中
2.2 Optional.get()方法(返回對象的值)
get()
方法是返回一個option的實例值 源碼:
publicTget(){
if(value==null){
thrownewNoSuchElementException("Novaluepresent");
}
returnvalue;
}
也就是如果value不為空則做返回,如果為空則拋出異常 "No value present" 簡單實例展示
Personperson=newPerson();
person.setAge(2);
Optional.ofNullable(person).get();
2.3 Optional.isPresent()方法(判讀是否為空)
isPresent()
方法就是會返回一個boolean類型值,如果對象不為空則為真,如果為空則false 源碼:
publicbooleanisPresent(){
returnvalue!=null;
}
簡單的實例展示:
Personperson=newPerson();
person.setAge(2);
if(Optional.ofNullable(person).isPresent()){
//寫不為空的邏輯
System.out.println("不為空");
}else{
//寫為空的邏輯
System.out.println("為空");
}
2.4 Optional.ifPresent()
方法(判讀是否為空并返回函數)
這個意思是如果對象非空,則運行函數體 源碼:
publicvoidifPresent(ConsumersuperT>consumer){
//如果value不為空,則運行accept方法體
if(value!=null)
consumer.accept(value);
}
看實例:
Personperson=newPerson();
person.setAge(2);
Optional.ofNullable(person).ifPresent(p->System.out.println("年齡"+p.getAge()));
如果對象不為空,則會打印這個年齡,因為內部已經做了NPE(非空判斷),所以就不用擔心空指針異常了
2.5 Optional.filter()方法(過濾對象)
filter()
方法大致意思是,接受一個對象,然后對他進行條件過濾,如果條件符合則返回Optional對象本身,如果不符合則返回空Optional
源碼:
publicOptionalfilter(PredicatesuperT>predicate){
Objects.requireNonNull(predicate);
//如果為空直接返回this
if(!isPresent())
returnthis;
else
//判斷返回本身還是空Optional
returnpredicate.test(value)?this:empty();
}
簡單實例:
Personperson=newPerson();
person.setAge(2);
Optional.ofNullable(person).filter(p->p.getAge()>50);
2.6 Optional.map()方法(對象進行二次包裝)
map()
方法將對應Funcation函數式接口中的對象,進行二次運算,封裝成新的對象然后返回在Optional中 源碼:
publicOptionalmap(FunctionsuperT,?extendsU>mapper){
Objects.requireNonNull(mapper);
//如果為空返回自己
if(!isPresent())
returnempty();
else{
//否則返回用方法修飾過的Optional
returnOptional.ofNullable(mapper.apply(value));
}
}
實例展示:
Personperson1=newPerson();
person.setAge(2);
StringoptName=Optional.ofNullable(person).map(p->person.getName()).orElse("name為空");
2.7 Optional.flatMap()方法(Optional對象進行二次包裝)
map()
方法將對應Optional< Funcation >
函數式接口中的對象,進行二次運算,封裝成新的對象然后返回在Optional中 源碼:
publicOptionalflatMap(FunctionsuperT,Optional>mapper){
Objects.requireNonNull(mapper);
if(!isPresent())
returnempty();
else{
returnObjects.requireNonNull(mapper.apply(value));
}
}
實例:
Personperson=newPerson();
person.setAge(2);
Optional