Java中NullPointerException的完美解决方案
2020-12-18 04:33
标签:现在 网上 other class follow 带来 string cer 另一个 我相信所有的Java程序猿一定都遇到过 前两点不需要特别的说明,后两点举个例子来说明一下: 在这个例子中,假如我们需要取到手机生成厂商的名字 由于不一定每个人都会有一个手机,所有在调用 一门设计语言本来就是来描述世界的,在这个事例中有的人有手机,有的人也可能没有手机,所以在调用 在遇到这种情况通常的做法是做null检查,甚至是每个地方可能发生null指针的做检查。 这里我已经试图在减少代码的层级,如果使用的是 吐槽了那么多现状的不好,现在可以祭出我们的解决方案了 由于有的人可能没有手机,有的人有,所以 而当我们在调用 当我们需要获取到手机的型号的时候可以这样: 当我们需要通过Person对象获取到Phone的型号是,会想到这样: 当我们写出来的时候发现编译器不能通过。是因为 这里需要用到另一个方法 取出 本人菜鸟,如果有任何写的不对的地方,欢迎在评论区指出 原创不易 转载请注明出处:https://silently9527.cn/archives/56 Java中NullPointerException的完美解决方案 标签:现在 网上 other class follow 带来 string cer 另一个 原文地址:https://blog.51cto.com/15049004/2561081null在Java中带来的麻烦
NullPointerException
,空指针在Java程序中是最常见的,也是最烦人的;它让我们很多程序猿产生了根深蒂固的感觉,所有可能产生空指针的地方都的加上if-else
检查,但是这带给我们很多麻烦
if-else
的空检查,甚至是多层嵌套,代码可读性下降无
假如一个人拥有一个手机,每个手机都有生成厂商,每个厂商都会有个名字,用类表示的话:public class Person {
private Phone phone;
public Phone getPhone() {
return phone;
}
}
public class Phone {
private Producer producer;
public Producer getProducer() {
return producer;
}
}
public class Producer {
private String name;
public String getName() {
return name;
}
}
public String getPhoneProducerName(Person person) {
return person.getPhone().getProducer().getName();
}
getProducer()
时可能会出现NullPointerException
。person.getPhone()
返回的值就应该包含有和无这两种情况,现在通过返回null
来表示无,但是在调用getProducer()
却又会抛出异常,这样就不太符合现实逻辑;所以把null
来用来表示无
不合适public String getPhoneProducerName(Person person) {
if (person.getPhone() == null) {
return "无名字";
}
if (person.getPhone().getProducer() == null) {
return "无名字";
}
return person.getPhone().getProducer().getName();
}
if-else
,代码的层级会更深,代码可读性下降。
Optional的简单介绍
Optional
;千呼万唤始出来,犹抱琵琶半遮面;那Optional
到底是个什么东西,我们一起来逐步解开它的面纱。Optional
本身只是对对象的简单包装,如果对象为空,那么会构建一个空的Optional
;这样一来Optional
就包含了存在和不存在两个情况, 接下来可以看下上面的例子改过之后public class Person {
private Optional
Phone
需要用Optional
包装起来;手机本身一定会有生产的厂商,厂商一定会有一个名字,所以这两个不需要用Optional
包装起来。这里我们会发现使用了Optional
会丰富代码的语义,让代码更加符合现实。phone.getProducer().getName()
的时候不需要做null指针的检查,如果说在这里发生了NullPointerException
,说明这里数据本身是有问题的,不符合现实,就应该让问题暴露出来,而不是像上面的代码一样把问题掩盖。
Optional的常用方法使用
1. Optional的创建方法
Optional
2. Optional值的获取方式
首先我们重新定义一下Phone类,除了有生产厂商之外,还有个型号;public class Phone {
private String model;
private Producer producer;
public Producer getProducer() {
return producer;
}
public String getModel() {
return model;
}
}
Optional
Optional
Person::getPhone
返回的是一个Optional<Phone>
,调用optionalPerson.map(Person::getPhone)
返回的就是Optional<Optional<Phone>>
,所以再.map
的就无法拿到手机型号,那如何能够让返回的结果不是Optional<Optional<Phone>>
,而是Optional<Phone>
呢?flatMap
。flatMap
和map
的区别,我在刚开始学习的时候,看到了网上的各种解释都很绕,看的很晕,最后直接打开源码来看,发现实现很简单,很容易理解,来看下源码:public Optional map(Function super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
public Optional flatMap(Function super T, Optional> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
map
方法在返回的时候会包装一层Optional
; flatMap
在返回的时候直接把函数的返回值返回了,函数的结果必须是Optional
;那么在前面的例子中我们直接调用flatMap
返回的结果就是Optional<Phone>
Optional
Optional
中的值对象:get、orElse、orElseGet、orElseThrow、ifPresent
NoSuchElementException
;所以当如果存在空值的话建议就不要调用该方法,因为这样和做null检查就没有区别了consumer
函数,如果值为空,那么这个方法什么都不做
假如我们需要过滤出手机型号IOS
的手机,并打印出型号,代码如下:Person person = new Person(Optional.of(new Phone("IOS")));
Optional
总结
Optional
来表示有和无的情况以及初始化的方式Optional
中经常使用到的方法
文章标题:Java中NullPointerException的完美解决方案
文章链接:http://soscw.com/index.php/essay/37002.html