欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java8之Optional类

程序员文章站 2022-04-20 21:10:55
写在前头 今天再看阿里的Java开发手册,里面异常处理第10条提到这样一个建议。 【推荐】防止 NPE ,是程序员的基本修养,注意 NPE 产生的场景:1 ) 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。反例: public int f() { retur ......

写在前头

今天再看阿里的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的问题,而且还非常的简洁。