Java判空方式有很多多,可以if是否为null或者采用Objects.isNull或者Objects.nonNull,或者其他工具类等都可以,本身写法也没什么问题,代码可读性也高,可能有时候不够简洁,所以Java8推出的Optional方式实现同样的功能,更加简洁,但是可读性降低了,这个根据需要权衡使用吧。对于Optional容器本身也会抛出空指针,他是直接抛出,用于快速定位,尽量避免空指针。
Objects.isNull();
Objects.nonNull();
Object == null;
... ...
1.Optional数组测试方式
/**
* 一、Optional 容器类:用于尽量避免空指针异常
* Optional.of(T t) : 创建一个 Optional 实例
* Optional.empty() : 创建一个空的 Optional 实例
* Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则直接抛出异常
* <p>
* isPresent() : 判断是否包含值
* orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
* orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
* map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
* flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
*/
public class TestOptional {
@Test
public void test7() {
List<Integer> list = new ArrayList<Integer>() {{
add( 1 );
add( 2 );
add( 3 );
}};
List<Object> objectList = null;
// 如果list为null就获取orElse中的内容,可以有效避免空指针
Optional.ofNullable( list ).orElse( new ArrayList<>() ).forEach( System.out::println );
Optional.ofNullable( objectList ).orElse( new ArrayList<>() ).forEach( System.out::println );
//下边就会抛出空指针
objectList.forEach( System.out::println );
//如果为null就会抛出指定异常,可以自定义异常
Optional.ofNullable( objectList ).orElseThrow( NullPointerException::new );
Optional.ofNullable( objectList ).orElseThrow( RuntimeException::new );
}
@Test
public void test4() {
Optional<Employee> op = Optional.of( new Employee( 101, "张三", 18, 9999.99 ) );
//为null的时候也会空指针
//Optional<Employee> op = Optional.of( null );
Optional<String> op2 = op.map( Employee::getName );
System.out.println( op2.get() );
Optional<String> op3 = op.flatMap( (e) -> Optional.of( e.getName() ) );
System.out.println( op3.get() );
}
@Test
public void test3() {
Optional<Employee> op = Optional.ofNullable( new Employee() );
//有值就获取,否则不执行
if (op.isPresent()) {
System.out.println( op.get() );
}
//如果op有值就获取值,没有值就去orElse中的值
Employee emp = op.orElse( new Employee( "张三" ) );
System.out.println( emp );
//如果op有值就获取值,没有值就去orElse中的值
Employee emp2 = op.orElseGet( () -> new Employee() );
System.out.println( emp2 );
}
@Test
public void test2() {
// 不允许为空,直接抛出空指针
Optional<Employee> op1 = Optional.ofNullable( null );
System.out.println( op1.get() );
//允许为空,但是get的时候回抛出空指针
Optional<Employee> op = Optional.empty();
System.out.println( op.get() );
}
/**
* Optional.ofNullable( null )也会抛出空指针
* 它所表达的思想是这里会直接抛出空指针快速定位
*/
@Test
public void test1() {
Optional<Employee> op = Optional.of( new Employee() );
Employee emp = op.get();
System.out.println( emp );
}
@Test
public void test5() {
Man man = new Man();
String name = getGodnessName( man );
System.out.println( name );
}
/**
* 需求:获取一个男人心中女神的名字
*/
public String getGodnessName(Man man) {
if (man != null) {
Godness g = man.getGod();
if (g != null) {
return g.getName();
}
}
return "苍老师";
}
/**
* 运用 Optional 的实体类
*/
@Test
public void test6() {
Optional<Godness> godness = Optional.ofNullable( new Godness( "林志玲" ) );
Optional<NewMan> op = Optional.ofNullable( new NewMan( godness ) );
String name = getGodnessName2( op );
System.out.println( name );
}
public String getGodnessName2(Optional<NewMan> man) {
return man.orElse( new NewMan() )
.getGodness()
.orElse( new Godness( "苍老师" ) )
.getName();
}
}
2.Optional对象测试方式
TestOptional
/**
* Optional避免空指针,采用默认值或者自定义抛出异常
* 使用场景:多层对象嵌套取值
*
*
**/
public class OptionalTest {
@Test
public void Test1() {
// 正常情况,都不为null,都可以正常执行
User user = User.builder().address( Address.builder()
.country( Country.builder().countryName( "nj" )
.build() )
.build() )
.build();
// user为null
user = null;
// Address 为null
user = User.builder().address( null ).build();
// country 为null
user = User.builder().address( Address.builder()
.country( null ).build() ).build();
OptTest( user );
}
public void OptTest(User user) {
// 第一种方式:存在空指针的风险,只要与一个对象为空就会空指针
String countryName = user.getAddress().getCountry().getCountryName();
System.out.println( "第一种方式:" + countryName );
// 第二种方式:各种if判断避免了空指针,但是if层级太深,代码冗长
if (user != null) {
Address address = user.getAddress();
if (address != null) {
Country country = address.getCountry();
if (country != null) {
String couName = country.getCountryName();
System.out.println( "第二种方式:" + couName );
}
}
}
// 第三种方式:代码简洁,避免空指针,武林那一步为空都会返回默认值
String counName = Optional.ofNullable( user )
.map( User::getAddress )
.map( Address::getCountry )
.map( Country::getCountryName )
.orElse( "china" );
System.out.println( "第三种方式:" + counName );
// 第三种方式:代码简洁,避免空指针,武林那一步为空都会返回自定义异常
String countryNameEx = Optional.ofNullable( user )
.map( User::getAddress )
.map( Address::getCountry )
.map( Country::getCountryName )
.orElseThrow( () -> new RuntimeException( "countryId is null" ) );
System.out.println( "第四种方式:" + countryNameEx );
}
}
user
/**
* @author zrj
* @version V1.0
* @since 2020/11/20
**/
@Data
@Builder
public class User {
private Integer userId;
private String userName;
private Address address;
}
@Data
@Builder
public class Address {
private Integer addressId;
private String addressName;
private Country country;
}
@Data
@Builder
public class Country {
private Integer countryId;
private String countryName;
}