# Java `Optional`示例

> 原文： [https://javatutorial.net/java-optional-example](https://javatutorial.net/java-optional-example)

Java 8 引入了`Optional`类，该类用于根据值是否存在来操纵数据。 您可以不使用此类而具有相同的功能，但是最终会产生混乱的代码。 换句话说，您的空检查将更少，而`NullPointerException`则不会。

![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)

让我举一个例子，说明为什么不使用`Optional`会导致问题。

## 未使用`Optional`

```java
public class NonOptionalImplementation {

    public static void main(String[] args) {

       Animal dog = new Animal(null, 5);
       String dogModified = dog.getName().toLowerCase();
       System.out.println(dogModified);
    }

 }

 class Animal {

    private String name;
    private int age;

    Animal(String n, int a) {
       this.name = n;
       this.age = a;
    }

    public String getName() {
       return this.name;
    }

    public int getAge() {
       return this.age;
    }

 }
```

您能发现哪里会出问题吗？ 显然，当我们到达`print`语句时，由于对象名称被故意设置为`null`，它将抛出`NullPointerException`。

## 输出

```java
Exception in thread "main" java.lang.NullPointerException
        at OptionalImplementation.main(OptionalImplementation.java:6)

```

## 使用`Optional`解决了此问题

```java
import java.util.Optional;
import java.util.*;

public class OptionalImplementation {

    public static void main(String[] args) {

       Animal dog = new Animal(null, 5);

       System.out.println(Optional.ofNullable(dog.getName()).orElse("Name not provided"));
    }

 }

 class Animal {

    private String name;
    private int age;

    Animal(String n, int a) {
       this.name = n;
       this.age = a;
    }

    public String getName() {
       return name;
    }

    public int getAge() {
       return this.age;
    }

 }
```

## 输出

```java
Name not provided
```

## 上述实现的简要拆分

*   我们正在创建一个非常简单的类，称为`Animal`，我们有 2 个具有构造函数的 getter 方法
*   在我们的主方法中，我们正在创建该`Animal`类的实例，但是我们还将第一个参数（恰好是名称）分配给`null`
*   `Optional.ofNullable`检查传递的字符串是否为`null`
*   之后，我们尝试打印值
*   我们有这个`.orElse()`方法调用，这基本上意味着：如果您要在其上调用该方法的字符串为 null，那么我将使用给出的参数进行打印
*   如果不为空，那么我将打印原始字符串
*   换句话说，如果字符串为`null`，它将打印默认值

是不是很酷？ 只要看看我们检查空值时代码的外观如何优雅即可。 而且安全！

为了进行比较，让我们尝试不使用`Optional`类而获得相同的结果。

```java
public class OptionalImplementation {

    public static void main(String[] args) {

       Animal dog = new Animal(null, 5);

       if (dog.getName() == null) {
           System.out.println("Name not provided");
       } 
       else {
           System.out.println(dog.getName().toLowerCase());
       }

    }

 }

 class Animal {

    private String name;
    private int age;

    Animal(String n, int a) {
       this.name = n;
       this.age = a;
    }

    public String getName() {
       return this.name;
    }

    public int getAge() {
       return this.age;
    }

 }
```

## 输出

```java
Name not provided
```

它有效..但是干净吗？ 我不这么认为！

您也可以使用`isPresent()`方法检查对象中是否存在值：

```java
import java.util.Optional;

public class OptionalImplementation {

    public static void main(String[] args) {
       Optional<Object> n = Optional.empty(); // creating an empty string

       System.out.println(n.isPresent());
       System.out.println(n);
    }
 }
```

## 输出

```java
false
Optional.empty
```

而已。 不是那么难，不是吗？ 甚至它都不是很容易理解，但是它也大大简化了您的代码，并且也非常易于阅读和维护。 如果要浏览`Optional`提供的所有方法，请查看官方 [Oracle 文档](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)。