Java8推出了Optional类,用来避免空指针异常,注意是尽可能的减少。
Optional的常用方法:
构造器:
Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t) : 若 t 不为 null,创建 Optional 实例,否则创建空实例
isPresent() : 判断是否包含值
常用方法:
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s) : 如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f) : 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
flatMap(Function mapper) :与 map 类似,要求返回值必须是Optional
举例:
package com.jv.java8.optional;
public class Cust {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cust other = (Cust) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Cust [name=" + name + "]";
}
public Cust() {
super();
// TODO Auto-generated constructor stub
}
public Cust(String name) {
super();
this.name = name;
}
}
package com.jv.java8.optional;
public class Account {
private Cust cust;
private String name;
private Integer gendor;
public Cust getCust() {
return cust;
}
public void setCust(Cust cust) {
this.cust = cust;
}
@Override
public String toString() {
return "Account [cust=" + cust + ", name=" + name + ", gendor=" + gendor + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cust == null) ? 0 : cust.hashCode());
result = prime * result + ((gendor == null) ? 0 : gendor.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (cust == null) {
if (other.cust != null)
return false;
} else if (!cust.equals(other.cust))
return false;
if (gendor == null) {
if (other.gendor != null)
return false;
} else if (!gendor.equals(other.gendor))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getGendor() {
return gendor;
}
public void setGendor(Integer gendor) {
this.gendor = gendor;
}
public Account() {
super();
// TODO Auto-generated constructor stub
}
public Account(Cust cust, String name, Integer gendor) {
super();
this.cust = cust;
this.name = name;
this.gendor = gendor;
}
}
package com.jv.java8.optional;
import java.util.Optional;
import org.junit.Test;
public class TestOptional {
@Test
public void test1() {
//制造一个空指针异常
Account acct = new Account();
System.out.println(acct.getCust().getName());//如愿以偿报了空指针异常,因为默认构造函数得到的ACCOUNT对象的CUST是空的
}
@Test
public void test2() {
NewAccount nAcct = new NewAccount();
System.out.println(nAcct.getCust().get());
/**
* 走到这里可能有老铁要问了,你还不是报异常了啊,虽然不是空指针异常,但是有了Optional,你可以很容易想到这种异常是出现在哪里,精彩的请继续往后看
*/
}
@Test
public void test3() {
NewAccount nAcct = new NewAccount();
System.out.println(nAcct.getCust().orElse(new Cust("乔布斯")));//很简单明了实现了我们之前好多行才能解决的问题吧
NewAccount acct = new NewAccount(Optional.of(new Cust("乔布斯")),"比尔盖茨",1);
System.out.println(acct.getCust().map(x->x.getName()).get());
}
}
对于写惯了if else的我来说,用Optional在大型系统中,特别是对象字段特别多的,且很容易为空,都用Optional真的划算吗???