Необязательный класс возмездия исключения нулевого указателя новых функций Java 8

Java

В серии новых функций Java8 мы представили поток, лямбда-выражение, обработку даты и времени DateTime и, наконец, закончили объяснением Немезиды Необязательный класс «NullPointerException».

задний план

Играем с NullPointerException в качестве разработчика каждый день. Каждый раз, когда принимается параметр или вызывается метод, стоит проверить, является ли он нулевым. Если вы не будете осторожны, исключение нулевого указателя появится как призрак.

В этой статье мы узнаем, как Java 8 позволяет избежать исключений нулевого указателя с помощью класса Optional.

Давайте сначала посмотрим, что мы будем делать, чтобы предотвратить исключение NullPointerException, когда мы не используем класс Optional.

public String getParentName(Person son) {
    if (son != null) {
        Person parent = son.getParent();
        if (parent != null) {
            return parent.getUsername();
        } else {
            return "--";
        }
    }

    return "--";
}

Для предотвращения исключений необходимо постоянно оценивать, является ли объект нулевым. Но если бизнес-логика будет более сложной, возникнет много лишнего. Вроде логично, но читабельность невысокая.

Чтобы решить связанные проблемы, в Effective Java очень сложно предложить, чтобы, если тип возвращаемого значения метода является коллекцией, избегать исключения NullPointerException, возвращая пустую коллекцию.

Давайте посмотрим, как будет выглядеть приведенный выше код после использования Optional.

public String getParentNameWithOptional(Person son) {
    return Optional.ofNullable(son).map(Person::getParent).map(Person::getUsername).orElse("--");
}

Проверьте код, чтобы увидеть, является ли Бог волшебным? !

Введение в необязательный класс

Введение класса java.util.Optional является хорошим решением для исключений нулевого указателя.Объявление класса выглядит следующим образом:

public final class Optional<T> {}

Класс java.util.Optional — это объект-контейнер, который инкапсулирует необязательное значение. Необязательное значение может быть нулевым. Если значение существует, вызовите метод isPresent(), чтобы вернуть значение true, и вызовите метод get(), чтобы получить значение .

В исходном коде будет обнаружено, что он не реализует интерфейс java.io.Serializable, поэтому его следует избегать в атрибутах класса, чтобы предотвратить непредвиденные проблемы.

В дополнение к классу Optional он также расширяет некоторые распространенные типы дополнительных объектов, такие как: OptionalDouble, OptionalInt, OptionalLong. Использование в основном аналогично.

Давайте узнаем о необязательном классе через конкретные операции и функции.

Создать необязательный объект

Есть три способа создать необязательный объект: empty(), of(), ofNullable(), все из которых являются статическими методами.

Если необязательный объект не имеет значения, используйте метод empty().

Optional empty = Optional.empty();

Если определено, что значение необязательного объекта не равно нулю, можно использовать метод of().

Optional stringOptional = Optional.of("Hello 公众号:程序新视界");

Если вы не уверены, что значение объекта Optional равно null, вы можете использовать ofNullable(). Например, в приведенном выше примере, если вы не уверены, является ли объект Person нулевым или нет, используется метод ofNullable(). Конечно, вы также можете передать null непосредственно в метод.

Optional ofNullOptional = Optional.ofNullable(null);

На этом этапе вы можете проверить, является ли значение в необязательном значении нулевым, вызвав его метод isPresent.

boolean bool = ofNullOptional.isPresent();
System.out.println(bool);

В этот момент, если вы напрямую вызовете метод get для получения значения, будет выдано исключение.

ofNullOptional.get();

get получает значение в необязательном

Значение в необязательном можно получить с помощью метода get, но если значение равно null, будет выдано исключение.

Optional ofNullOptional = Optional.ofNullable(null);
ofNullOptional.get();

Информация об исключении:

java.util.NoSuchElementException: No value present
    at java.util.Optional.get(Optional.java:135)
...

На данный момент необходим другой метод: isPresent(). Этот метод может определить, есть ли значение в Optional, если есть значение, возвращает true, если нет, возвращает false.

Optional ofNullOptional = Optional.ofNullable(null);
boolean bool = ofNullOptional.isPresent();
if(bool){
    ofNullOptional.get();
}

карта, чтобы получить значение в необязательном

Для объектных операций значения также можно получить через карту, что и имеет место в первом упрощенном примере.

Optional<Person> sonOptional = Optional.ofNullable(son);
System.out.println(sonOptional.map(Person::getUsername));

Метод карты, если есть значение, выполняет вызов функции карты, чтобы получить возвращаемое значение. Если возвращаемое значение не равно null, создайте необязательный элемент, содержащий возвращаемое значение карты в качестве возвращаемого значения метода карты, в противном случае верните пустой необязательный элемент.

flatMap получает значение в необязательном порядке

Если есть значение, он возвращает возвращаемое значение типа Необязательный, в противном случае он возвращает пустой Необязательный. flatMap похож на метод карты. Но возвращаемое значение преобразователя в flatMap должно быть необязательным. В конце вызова flatMap не оборачивает результат в необязательный.

Optional<Person> sonOptional = Optional.ofNullable(son);
sonOptional.flatMap(OptionalTest::getOptionalPerson);

Вызывается другой метод текущего класса OptionalTest:

public static Optional<Person> getOptionalPerson(Person person){
    return Optional.ofNullable(person);
}

orElse получить значение в необязательном

метод orElse, если есть значение, возвращает, в противном случае возвращает заданное значение как значение по умолчанию;

Optional.empty().orElse("--");

В приведенном выше случае будет возвращено «--».

Здесь эта операция имеет тот же эффект, что и тринокулярная операция.

str != null ? str : "--"

orElseGet, чтобы получить значение в необязательном

Метод orElseGet() аналогичен методу orElse(), но значение по умолчанию генерируется иначе. Этот метод принимает параметр функционального интерфейса поставщика для создания значений по умолчанию;

Optional.empty().orElseGet(() -> {
            String a = "关注";
            String b = "公众号:程序新视界";
            return a + b;
        });

Очевидно, что здесь можно обрабатывать больше бизнес-логики.

orElseThrow получает значение в необязательном

Метод orElseThrow() аналогичен методу get(). NullPointerException будет сгенерировано, когда значение равно null, но этот метод может указать тип выбрасываемого исключения.

Optional.empty().orElseThrow(()-> new RuntimeException("请先关注公众号!"));

В это время печатается ненормальная информация:

Optional.empty().orElseThrow(()-> new RuntimeException("请先关注公众号!"));

судить и действовать

Метод ifPresent может определить значение и затем распечатать его, а полученный параметр является функциональным интерфейсом потребителя.

Optional.of("公众号:程序新视界").ifPresent(System.out::println);

Конечно, другие сложные операции также могут быть выполнены в функциях:

Optional.of("公众号:程序新视界").ifPresent((val)->{
            System.out.println("欢迎关注" + val);
        });

метод filter() для фильтрации

Метод filter() можно использовать для определения того, соответствует ли дополнительный объект заданному условию, и обычно он используется для условной фильтрации:

Optional.of("公众号:程序新视界").filter((val)->{
    return val.contains("程序新视界");
});
// 简化写法
Optional.of("公众号:程序新视界").filter((val)-> val.contains("程序新视界"));

Непонимание

Непонимание использования Необязательного заключается в следующем:

  • Правильно используйте метод создания и попробуйте выбрать метод ofNullable, если вы не уверены, является ли он нулевым.
  • Избегайте его использования для переменных-членов (по причинам, упомянутым выше);
  • Избегайте прямого вызова методов get и isPresent объекта Optional;

Последнее может быть трудно понять.Представьте, если вы сначала используете метод isPresent, чтобы узнать, существует ли он, а затем решаете, вызывать метод get или нет, это то же самое, что и предыдущее суждение ifelse.

Java8 поддерживает функциональное программирование, и многие новые API-интерфейсы могут быть выражены в функциональном программировании, и класс Optional — один из них.

резюме

На этом материалы, связанные с новыми функциями Java 8, закончились.

Статьи, посвященные серии новых функций Java8:

Обратите внимание на общедоступную учетную запись «Program New Vision», ответьте «001» и получите PDF-версию всей серии «Новые функции Java8».

Оригинальная ссылка: "Необязательный класс возмездия исключения нулевого указателя новых функций Java 8


Программа Новые Горизонты: Захватывающие и растущие нельзя пропустить

程序新视界-微信公众号