为什么Java8中的Optional类是final的

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;
    }
}

显然已经偏离了该类的初衷。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,079评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,786评论 18 399
  • 可燃冰:石化机械 为龙头,引发全面发酵,但是空间高度不知道。石化油服,海默科技,中化岩土,博麦克,中海油服,潜能恒...
    天涯别院阅读 151评论 0 0
  • 这几个月里,c城四环内的房租发疯一样涨了几番,而我那少的可怜的工资让人怀疑我究竟是做办公室助理,还是在为扫厕所的...
    周二需要阴天阅读 257评论 0 1
  • 接近暮春的时候,郊外的路上很多树已经落了花,地上撒满的半枯萎花瓣还带着水分;徐透每次骑单车经过,看着这些被碾压或者...
    狩祟阅读 300评论 0 0