Java8之Optional类
写在前头
今天再看阿里的java开发手册,里面异常处理第10条提到这样一个建议。
【推荐】防止 npe ,是程序员的基本修养,注意 npe 产生的场景:
1 ) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 npe。
反例: public int f() { return integer 对象}, 如果为 null ,自动解箱抛 npe 。
2 ) 数据库的查询结果可能为 null 。
3 ) 集合里的元素即使 isnotempty ,取出的数据元素也可能为 null 。
4 ) 远程调用返回对象时,一律要求进行空指针判断,防止 npe 。
5 ) 对于 session 中获取的数据,建议 npe 检查,避免空指针。
6 ) 级联调用 obj . geta() . getb() . getc(); 一连串调用,易产生 npe 。
正例:使用 jdk8 的 optional 类来防止 npe 问题。
里面的正确示例提示我们用java8的optional类来防止npe的问题。
那我们今天就看看这个optional类吧
optional类
-
类方法
序号 | 方法 & 描述 |
---|---|
1 |
static <t> optional<t> empty()
返回空的 optional 实例。 |
2 | boolean equals(object obj)
判断其他对象是否等于 optional。 |
3 | optional<t> filter(predicate<? super <t> predicate)
如果值存在,并且这个值匹配给定的 predicate,返回一个optional用以描述这个值,否则返回一个空的optional。 |
4 | <u> optional<u> flatmap(function<? super t,optional<u>> mapper)
如果值存在,返回基于optional包含的映射方法的值,否则返回一个空的optional |
5 | t get()
如果在这个optional中包含这个值,返回值,否则抛出异常:nosuchelementexception |
6 | int hashcode()
返回存在值的哈希码,如果值不存在 返回 0。 |
7 | void ifpresent(consumer<? super t> consumer)
如果值存在则使用该值调用 consumer , 否则不做任何事情。 |
8 | boolean ispresent()
如果值存在则方法会返回true,否则返回 false。 |
9 | <u>optional<u> map(function<? super t,? extends u> mapper)
如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的optional作为map方法返回值,否则返回空optional。 |
10 |
static <t> optional<t> of(t value)
返回一个指定非null值的optional。 |
11 |
static <t> optional<t> ofnullable(t value)
如果为非空,返回 optional 描述的指定值,否则返回空的 optional。 |
12 | t orelse(t other)
如果存在该值,返回值, 否则返回 other。 |
13 | t orelseget(supplier<? extends t> other)
如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。 |
14 | <x extends throwable> t orelsethrow(supplier<? extends x> exceptionsupplier)
如果存在该值,返回包含的值,否则抛出由 supplier 继承的异常 |
15 | string tostring()
返回一个optional的非空字符串,用来调试 |
我们可以看到optional总共也就10+个方法,其中有三个static方法。并且optional的构造方法是private,不能new出来。
所以我们一般用这三个static来获取optional的对象。
-
of && ofnullable
1 public static <t> optional<t> of(t value) { 2 return new optional<>(value); 3 } 4 5 public static <t> optional<t> ofnullable(t value) { 6 return value == null ? empty() : of(value); 7 }
很明显 of 对null对象没有做任何处理,ofnullable才做了处理。所以当我们不知道传入的对象是否为null的时候,我们应该选择用 ofnullable来做处理。
-
map
1 public<u> optional<u> map(function<? super t, ? extends u> mapper) { 2 objects.requirenonnull(mapper); 3 if (!ispresent()) 4 return empty(); 5 else { 6 return optional.ofnullable(mapper.apply(value)); 7 } 8 }
如果我们想获取object里面的值的话,我们就需要用到这个map。
例子
1 public class optionaltest { 2 public static void main(string[] args) { 3 person person = new person("zhangsan", 18); 4 string name = getname(person); 5 system.out.println(name); 6 } 7 8 private static string getname(person person) { 9 if (objects.isnull(person)) { 10 return "unknown"; 11 } 12 return person.getname(); 13 } 14 15 }
我们看上面的这个例子。
我们有一个函数 getname 作用是获取person对象的名字。但我并不知道这个person是否为null。
所以我要进行一个判断,判断person是否为空,在做决定。
但如果我们使用optional类的话,我们可以这样写
1 public class optionaltest { 2 public static void main(string[] args) { 3 person person = new person("zhangsan", 18); 4 string name = getname(person); 5 system.out.println(name); 6 } 7 8 private static string getname(person person) { 9 string name = optional.ofnullable(person).map(x -> x.getname()) 10 .orelse("unknown"); 11 return name; 12 } 13 }
如果传入的为空,它会自动new一个 optional<t> t = (optional<t>) empty;
有效的处理到了null的问题,而且还非常的简洁。
推荐阅读
-
iOS开发之封装一个水平菜单栏类的教程
-
Java8与传统的日期和时间类详解
-
Java8语法中获取程序耗时以及Period,Duration,ChronoUnit类的使用
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit
-
Java8中使用以下类计算日期时间差:Period、Duration、ChronoUnit
-
php数据访问之增删改查操作 php操作mysql数据库 php操作mysql数据库类 phpcms 数据库操
-
C++ 特殊类成员之静态成员变量学习讲解
-
PHP数据库操作之基于Mysqli的数据库操作类库
-
java之反射调用某个接口的所有实现类
-
重温java知识(三十五、反射机制之十一:反射与简单Java类---设置多种数据类型)