Необязательная плоская карта в Java имеет исключение NullPointerException - PullRequest
0 голосов
/ 08 декабря 2018

Необязательный параметр используется, чтобы избежать исключения NullPointerException в Java 8.

Но код имеет исключение NullPointerException, когда я использую необязательную плоскую карту.

Код, как показано ниже:

import java.util.Optional;
public class test2 {
  public static class Car {
    public Optional<Insurance> insurance;

    public Optional<Insurance> getInsurance() {
      return insurance;
    }
  }

  public static class Insurance {
    public String name;

    public String getName() {
      return name;
    }
  }

  public static class Person {
    public Optional<Car> car;

    public Optional<Car> getCar() {
      return car;
    }
  }
  public static String getCarInsuranceName(Optional<Person> person) {
    return person.flatMap(Person::getCar)
            .flatMap(Car::getInsurance)
            .map(Insurance::getName)
            .orElse("Unknown");
  }
  public static void main(String[] args) {
    Person person = new Person();
    Car car = new Car();
    Insurance insurance = new Insurance();
//    insurance.name = "test";
//    car.insurance = Optional.of(insurance);
    person.car = Optional.of(new Car());
    String result= getCarInsuranceName(Optional.of(person));
    System.out.println(result);
  }
}

Информация о консолиПеременная :

Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.util.Optional.flatMap(Optional.java:241)
    at test2.getCarInsuranceName(test2.java:29)
    at test2.main(test2.java:41)

person действительно не имеет страховки.Но я хочу получить результат Unknown, а не NullPointerException.

Java-версия:

openjdk version "1.8.0_192"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_192-b12)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.192-b12, mixed mode)

Когда person имеет insurance, а insurance не имеет name Я получил Unknown.

Я хочу знать Почему?

1 Ответ

0 голосов
/ 08 декабря 2018

Поле insurance для Car всегда null.Никогда не позволяйте Optional быть null, это отрицает саму идею наличия Optional.И будет очень часто вызывать удивительные NullPointerException.Это то, что происходит и в вашем коде.

Я предлагаю следующую версию класса Car:

    public static class Car {
        private Insurance insurance = null;

        public Optional<Insurance> getInsurance() {
            return Optional.ofNullable(insurance);
        }
    }

Это устраняет проблему, поэтому вывод теперь такой:

Неизвестно

Нет смысла (что я вижу) в объявлении insurance и Optional.Достаточно того, что ваш получатель возвращает один.Optional в основном для возвращаемых значений.У него мало других полезных применений.

РЕДАКТИРОВАТЬ: @chrylis прокомментировал и, похоже, не нравится комбинация простого ссылочного поля и получателя, возвращающего Optional.Я не вижу в этом ничего плохого, но если вы предпочитаете оставить свое поле равным Optional, как в вопросе, это, безусловно, возможно.Тогда вам просто нужно убедиться, что это не null:

public static class Car {
    private Optional<Insurance> insurance = Optional.empty();

    public Optional<Insurance> getInsurance() {
        return insurance;
    }
}

Это также исправляет программу, поэтому мы получаем вывод выше.

Должен ли метод получения возвращатьOptional обсуждается в этом вопросе: должен ли получатель Java 8 возвращать необязательный тип? Мой первый приведенный выше фрагмент, похоже, больше следует рекомендациям наименее одобренного ответа Марка .

...