拒绝非空判断,我们一起来折腾下java8
的新特性optional
类 吧;
概念 为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Java 8类库 引入了一个同名的Optional类。实际上是个Optional容器类:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测,使你从繁琐的非空判断中解脱出来,写出更加优雅的代码!
快速上手 废话不多说,看源码一个个方法捋一遍!
私有方法和构造器
1 2 3 4 5 6 7 8 9 10 11 12 private static final Optional对象<?> EMPTY = new Optional <>();private final T value;private Optional () { this .value = null ; } private Optional (T value) { this .value = Objects.requireNonNull(value); }
从上面可以看出我们不能通过构造器创建一个Optional 对象,那么我们就来结合代码例子看看可以通过哪些方法创建Optional对象。
其他方法
1 2 3 4 5 6 Optional<String> optional1 = Optional.empty(); Optional<String> optional2 = Optional.of("hello,optional" ); Optional<String> optional3 = Optional.ofNullable(null );
get
1 2 3 4 5 6 7 8 9 10 11 System.out.println(optional2.get());
isPresent
1 2 3 4 5 6 7 System.out.println(optional2.isPresent());
ifPresent
1 2 3 4 5 6 7 8 9 UserInfo userInfo = new UserInfo (1 ,"小明" ,"深圳" );Optional.ofNullable(userInfo).ifPresent(u -> System.out.println("The user name is : " + u.getName()));
filter
1 2 3 4 5 6 7 8 9 10 11 System.out.println(Optional.ofNullable(userInfo).filter(u ->u.getId() > 1 ).isPresent());
map
1 2 3 4 5 6 7 8 9 10 11 12 System.out.println(Optional.ofNullable(userInfo).map(u -> Optional.u.getName()).get());
flatMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Optional<Integer> integer = Optional.ofNullable(userInfo).flatMap(u -> Optional.ofNullable(u.getId())); System.out.println(integer.get());
orElse()
1 2 3 4 5 6 7 8 9 userInfo = null ; String uName = Optional.ofNullable(userInfo).map(u -> u.getName()).orElse("Unknown name" );System.out.println(uName);
orElseGet
1 2 3 4 5 6 7 8 9 10 11 userInfo = null ; String uName = Optional.ofNullable(userInfo).map(u -> u.getName()).orElseGet(() -> "unknown name" );System.out.println(uName);
orElseThrow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 UserInfo userInfo1 = new UserInfo (2 ,"小花" ,null );String exception1 = Optional.ofNullable(userInfo1).map(u -> u.getName()).orElseThrow(() -> new Exception ("没有获取到名字" )); System.out.println(exception1); String exception2 = Optional.ofNullable(userInfo1).map(u -> u.getPassword()).orElseThrow(() -> new Exception ("没有获取到密码" )); System.out.println(exception2);
equals,hacode,toString 最后这三个都重写了Object的方法,其实没什么好说的,提一下:
equals使用Objects.equals(value, other.value) ,那意味着我们写equals判断时也应该这么写!
hashCode使用Objects.hashCode(value)
toString使用了三目运算和String.format(“Optional[%s]”, value) 占位符,意味着我们有些打印日志可以这么写。这就是面向源码学习,多借鉴借鉴还是很不错滴!
小结:至此,我们已经从头到尾看了遍optional底层的实现了! 然后平时过滤啥的知道用filter,改变值用map,判空用isPresent, if else 判断啥的用orElse 或者 orElseGet了吧,那就动手实践起来,话说最近在看一本书《重构改善既有代码的设计》,很不错推荐一哈!