为什么Java8中的Optional类是final的
2018-08-03 本文已影响0人
断臂残猿
Java8的Optional类给我们发日常开发中规避null判断提供了极大便利,现在我的代码中已经几乎很少使用if (sth == null)
的写法,基本都用Optional.ofNullable(sth)
了。
但是如果使用过程中感觉Optional的API不够用怎么办?
比如我想实现这样的效果:
if (sth == null) {
throw new Exception();
} else {
doSth();
}
Optinal提供了ifPresent
来执行非空时的操作,但是没有提供类似ifNotPresent
的操作符。那该怎么办呢?总不能这样写吧:
if (opt.isPresent()) {
doSth(opt.get());
} else {
throw new Exception();
}
太不伦不类了,不是纯粹的函数式编程。
Java9给Optional类添加了一个方法
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
if (value != null) {
action.accept(value);
} else {
emptyAction.run();
}
}
比如jdk自带的模块分析器中有这样的代码:
找到模块就add,否则log。
所以自然而然的想到模仿这个方法,自定义一下Optional类。
可是回头一看:Optional类是申明为final
的!!没法继承啊!
为什么呢?
因为像Optional类和LocalDateTime类都是值敏感的。jdk要求把值敏感的类设计成不可变类,否则对象就可以被变更。
值敏感类一般有这么几个特征要求:
- 申明为
final
- 根据值来自定义
equals()
和hashCode()
- 绝对使用
equals()
方法而不是==
进行比较 - 没有公开的构造器,而是提供工厂方法
如果值敏感却可以继承,我们就可以写出这样的代码:
public static void main(String[] args) {
System.out.println(OptionalNotFinal.of(3).b);
System.out.println(MyOptional.of(3).set(5).b);
}
private static class OptionalNotFinal {
private final int b;
private OptionalNotFinal(){
b = 0;
}
private OptionalNotFinal(int b) {
this.b = b;
}
public static OptionalNotFinal of(int b) {
return new OptionalNotFinal(b);
}
}
private static class MyOptional extends OptionalNotFinal {
private int b;
private MyOptional(){
b = 0;
}
private MyOptional(int b) {
this.b = b;
}
public static MyOptional of(int b) {
return new MyOptional(b);
}
public MyOptional set(int b) {
this.b = b;
return this;
}
}
显然已经偏离了该类的初衷。