java8新特性 Optional

总述

Optional 为java8的新特性

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional 类的引入很好的解决空指针异常。

类声明

java.util.optional类的声明
public filnal class Optional extends Object

类常用的方法

序号方法描述
1static Optional empty()返回空的 Optional 实例。
2boolean equals(Object obj)判断其他对象是否等于 Optional。
3Optional filter(Predicate<? super predicate>)如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。
4 Optional flatMap(Function< ? Super T>,Optional mapper)如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
5T get()如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
6boolean isPresent()如果值存在则方法会返回true,否则返回 false。
7static Optional of(T value)返回一个指定非null值的Optional。
8static Optional ofNullable(T value)如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
9T orElse(T other)如果存在该值,返回值, 否则返回 other。
10T orElseGet(Supplier<? extends T> other)如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
11 T orElseThrow(Supplier<? extends X> exceptionSupplier)如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常

Optional 实例

import java.util.Optional;
 
public class Java8Tester {
   public static void main(String args[]){
   
      Java8Tester java8Tester = new Java8Tester();
      Integer value1 = null;
      Integer value2 = new Integer(10);
        
      // Optional.ofNullable - 允许传递为 null 参数
      Optional<Integer> a = Optional.ofNullable(value1);
        
      // Optional.of - 如果传递的参数是 null,抛出异常 NullPointerException
      Optional<Integer> b = Optional.of(value2);
      System.out.println(java8Tester.sum(a,b));
   }
    
   public Integer sum(Optional<Integer> a, Optional<Integer> b){
    
      // Optional.isPresent - 判断值是否存在
        
      System.out.println("第一个参数值存在: " + a.isPresent());
      System.out.println("第二个参数值存在: " + b.isPresent());
        
      // Optional.orElse - 如果值存在,返回它,否则返回默认值
      Integer value1 = a.orElse(new Integer(0));
        
      //Optional.get - 获取值,值需要存在
      Integer value2 = b.get();
      return value1 + value2;
   }
}

输出结果为:
$ javac Java8Tester.java
$ java Java8Tester
第一个参数值存在: false
第二个参数值存在: true
10

示例重点解析:正常情况为value1 + value2=null+10会报错,使用Optional后可以计算值

Optional在SpringBoot中的应用之一

Spring Boot 2.0中,在将原来的泛型改为了Optional,旨在让我们的代码更简洁。

Optional findById(ID var1)

实践

Optional

很简单的一个类,点开它的源代码,其中所有的方法都是与null相关联的。

这是一个简化我们处理null的类。
这是一个简化我们处理null的类。
它就是一个容器,其中有我们想要的对象,但是该对象有时候会是空,所以我们需要使用Optional封装好的方法来获取需要的对象。从而很好地避免了空指针异常。

错误示范

我看到网上很多人这么写:catRepository.findById(id).get();
下面是Spring Boot 1.5的写法,那请问:如果上面的写法是正确的,那为什么还要大费周章设计一个Optional呢?
catRepository.findOne(id);

分析

通过get是能获取到我们需要的对象。

但是看看get的源代码,这样写,抛出了NoSuchElementException异常,这个异常我们没法在全局中处理它。

public T get() {   
	if (value == null) {     
	throw new NoSuchElementException("No value present");   
	}   
return value; } 

因为NoSuchElementException覆盖的范围太广了,只要是Optional中有null就会抛出NoSuchElementException,很多情况下都会造成这种异常,那我们究竟要给用户一个什么样的提示信息好呢?最后还是给出500服务器异常,那异常处理的意义何在呢?

所以我们需要用Optional来抛出一个有特定范围的能被全局准确处理的异常。

Cat cat = catRepository.findOne(id); 
if (null == cat) {   
throw new EntityNotFoundException("该实体找不到"); 
} 
return cat; 

思想都是一样,我们不过是用一种更简洁的写法实现上面的功能。

实现

没错,就像下面一样,我们只需要一行代码!

public Cat findById(Long id) {   
return catRepository.findById(id).orElseThrow(EntityNotFoundException::new); } 

findById返回一个Optional,然后调用该对象的orElseThrow方法。

orElseThrow方法,如果存在,返回包含的值,否则抛出异常。

该方法的参数是一个lamda表达式。这里就不深究lamda表达式的几种类型了,如果感兴趣可以自行研究下Function、Consumer、Predicate、Supplier这四个函数式接口的区别。

所以传一个lamda表达式进去,然后IDEA会给出警告:

在这里插入图片描述Can be replaced with method reference

该lamda表达式能被一个方法引用代替,Alt + Enter,我们最终的代码就长这样:
在这里插入图片描述

这里的::是lamda表达式的一种简写,是Java8中的新特性,看着可能有点奇怪,原来,编译器比程序员聪明多了。

异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {    
 @ExceptionHandler(EntityNotFoundException.class)   
 public ResponseEntity<String> entityNotFoundHandler() {    
  return new ResponseEntity<>("您要找的实体不存在", HttpStatus.NOT_FOUND);   } } 

写个控制器增强,全局处理异常,这里的RestControllerAdvice又是一个组合注解:

处理异常,同时以Json的格式返回。

另附一张Optional的API

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java8中的Optional类是一个容器对象,可以包含null或非null值。它提供了一种优雅的方式来处理null值,避免了NullPointerException异常的出现。Optional类可以用于返回值、方法参数和实例变量等场景中,使代码更加简洁、清晰和安全。使用Optional类可以使代码更加健壮,减少了代码中的null检查和异常处理,提高了代码的可读性和可维护性。 ### 回答2: Optional类是Java 8中新引入的一个类,它的主要作用是在避免NullPointerException的情况下将null值返回给调用者。这个类是一个容器对象,它可以保存非空的对象,也可以保存空值(null)。 Optional类提供了通过判断一个对象是否为空来避免空指针异常的方式。它可以在代码中替换传统的null判断,这样可以更加方便地编写代码,并且可以使代码更加健壮。 在Java中,如果一个方法返回值为null,那么在调用该方法返回值的时候,会有可能抛出NullPointerException异常。而Optional类的出现可以帮助我们避免这种情况的出现,在调用Optional类的get()方法时,如果Optional类中保存的对象不为null,就会返回该对象,否则抛出一个NoSuchElementException异常。 Optional类还提供了一些方法来简化代码,比如orElse()方法,如果Optional类中保存的对象不为null,则返回该对象,否则返回指定的default值。还有ifPresent()方法,当Optional类中保存的对象不为null时,会执行指定的代码,否则不执行。 总之,Optional类是Java 8中一个很有用的类,它可以帮助我们更加方便地处理null值,避免空指针异常的出现,并且可以简化代码。但是需要注意的是,不应该滥用Optional类,因为它并不是完美的解决方案,有时候需要对null值进行特殊处理。 ### 回答3: Java 8在语言层面上增加了一个新的类:Optional。这是一个特殊的容器对象,可以包含一个null或非null的值。 Optional的目的是解决Java中的null引用问题。在Java中,如果一个变量被赋值为null,而我们试图调用该变量所对应的方法,那么就会出现NullPointerException异常。 使用Optional可以避免这种情况的发生。如果一个变量是Optional对象,那么我们必须显式地检查该对象是否包含非null的值,才能对其进行操作。这样,在我们试图调用该变量所对应的方法之前,就可以避免空指针异常的发生。 Optional类提供了很多方法来判断是否有值、获取值、如果没有值则返回默认值等等,使得我们可以更加方便地处理空值。 下面是一些Optional类提供的方法: 1. Optional.of(T value):创建一个包含非null值的Optional对象,如果T为null,则抛出NullPointerException异常。 2. Optional.ofNullable(T value):创建一个Optional对象,如果T为null,则该对象为空。 3. Optional.empty():创建一个空的Optional对象。 4. get():如果值存在,则返回该值,否则抛出异常。 5. orElse(T other):如果值存在,则返回该值,否则返回其他默认值。 6. isPresent():返回一个boolean类型的值,表示该Optional对象是否包含值。 7. ifPresent(Consumer<? super T> consumer):如果该Optional对象包含值,则对该值执行给定的操作。 在编写Java程序时,我们应该始终努力避免使用null值。使用Optional类,可以使得我们的代码更加健壮、可读性更强。但是,过多地使用Optional可能会导致代码过于冗长,所以在使用的过程中需要权衡利弊。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值