Как Java изящно обрабатывает NPE

Spring Boot Java

1. Введение

заJavaДля разработчиков,nullтип головной боли, который может возникнуть, если вы не будете осторожныNPE(нулевой указатель) проблема. СлишкомJavaЯзык является одной из важных причин, по которой людей критикуют. прежде чем мы устраним одиозноеNPEПрежде чем мы перейдем к вопросу, давайте рассмотрим концепцию null в Java.

2. ноль в Java

Переведено сДокументация по Oracle Java

В языке Java есть два типа, один из нихбазовый тип, другойтип ссылки. Существует также специальный тип без имени, выражениеnull. так какnullТипы не имеют имен, поэтому их невозможно объявить какnullпеременная типа или преобразуется вnullтип.nullЦитатаnullЕдинственное возможное значение для выражения типа.nullСсылки могут быть приведены к любому типу ссылки. На самом деле программисты могут игнорироватьnullтипа, можно считать, чтоnullПросто специальный символ, который может быть любым ссылочным типом.

Из приведенного выше описания мы можем понять, что,На самом деле null — это просто идентификатор ключевого слова. Это не тип и не объект. Он не может напрямую объявлять null и преобразовываться в null. На него можно только ссылаться, а null можно преобразовать в любой ссылочный тип. Когда на объект ссылочного типа Java ссылаются как на null, это означает, что текущий объект не ссылается на объект и для него не выделяется память.Это также основная причина нулевых указателей, когда мы вызываем методы для объектов, на которые нет ссылок. в большинстве случаевJavaИспользование разработчикаnullОн предназначен для выражения того, чего не существует.

3. Решение проблемы NPE

Часто у нас есть собственные ожидания относительно существования данных, но такие ожидания не могут быть нами напрямую проконтролированы.Смысл, выражаемый возвращаемым значением null, не ясен и слишком расплывчат.О нем часто судят по тому, соответствует ли онnullчтобы избежать проблемы с нулевым указателем. Итак, инженеры Google в своемGuavaРазработана библиотека классов инструментовOptional<T>решатьnullнеуправляемые вопросы. заставить вас использоватьnullможно использовать более легко и ясноnullи помочь вам избежать прямого использованияnullвызванные проблемы.Java 8Поглотите этот дизайн. мы можем напрямую использоватьJavaкоторый предоставилOptionalрешить проблему с нулевым указателем. Далее будем учитьсяJava 8серединаOptional.

4. Необязательно в Java 8

в Яве 8Optionalявляется классом-оболочкой для необязательного значения. Его значение не только в том, чтобы помочь нам упроститьNPEрешение проблем, но иJavaОтличное дополнение к функциональному программированию. Мы будем рядомAPIОбъяснено, чтобы помочь вам использовать их в реальной разработке.

4.1 Необязательное объявление

OptionalМожет быть объявлен только через статические методы. Он предоставляет три статических метода:

empty()возвращает значениеnullизOptionalПример

  Optional<Object> empty = Optional.empty();

of(T)вернуть значение неnullизOptionalПример

 Optional<String> nonNull = Optional.of("Felordcn");

ofNullable()Возвращает значение, которое может бытьnullизOptionalПример

 // value 值来自其它不确定的来源
 String value = SomeApi.source();
 // 可能为 null 
 Optional<String> nullable = Optional.ofNullable(value);
 // 也可能不为 null 
 Optional<String>  hasValue = Optional.ofNullable(value);
    

4.2 Другие методы

isPresent()вернуть, если значение существуетtrue, иначе возвратfalse. еслиOptionalЗначение не определено, вы можете использовать этот метод для проверки безопасности

 Optional<String> nonNull = Optional.of("Felordcn");
  // true      
  boolean present =nonNull.isPresent();

get()ПолучатьOptionalЗначение в выбрасывается, если пустоNoSuchElementExceptionаномальный

 Optional<String> nonNull = Optional.of("Felordcn");
  // Felordcn      
  String str = nonNull.get();

ifPresent(Consumer)Если значение существует, оно потребляется потребляющей функцией.ConsumerПотребляй, иначе ничего не делай.isPresent()Расширенное издание


      //  非空打印出字符串     
      nullable.ifPresent(System.out::println);
     
     //等同于
      if (nullable.isPresent()) {
                 System.out.println(nonNull);
      }

filter(Predicate)Если значение удовлетворяет функции предикатаPredicateзатем верните этоOptional, иначе возвратOptional.empty()

 Optional<String> nonNull = Optional.of("Felordcn");
 Optional<String> felord = nonNull.filter(s -> s.startsWith("Felord"));
 // str = "Felordcn"
 String str = felord.get();

map(Function)Получить атрибут элементаOptional. Если имуществоnullвозвращениеOptional.empty(), иначе вернуть соответствующее значениеOptional

 Optional<User> userOpt = Optional.ofNullable(user);
//  username 为空 则为 空  Optional  
 Optional<String> usernameOpt = userOpt.map(User::getUsername);

flatMap(Function)иногда мы возвращаемсяOptional<Optional<T>>Очень неудобно обрабатывать, нам нужно расширить элемент, мы можем использовать этот метод для обработки, см.Stream Apiродственные методы в

orElse(other)еслиOptionalЗначение существует, возвратOptional, в противном случае укажитеOptional

orElseGet(Supplier)еслиOptionalЗначение существует, возвратOptional, иначе укажите исполнениеSupplierфункция для получения значения

orElseThrow(Supplier<? extends Throwable>)еслиOptionalЗначение существует, возвратOptional, иначе выдает указанныйSupplierИсключение, предоставляемое функцией

4.3 Новые API в Java 9

or(Supplier) orElseGetтип улучшения. Возвращает не только конкретное значение, но и функциональный возвратOptional

stream()будетOptionalиStreamпройти через

ifPresentOrElse(Consumer) ifPresentМетод обеспечивает логику потребления после значения, а логика без значения не предоставляет запись. новый методifPresentOrElseкомпенсировать этот недостаток

5. Неправильное понимание опционального

OptionalОчень ароматный, но злоупотреблять им нельзя. Опасным ходом являетсяOptionalпередается в качестве аргумента метода. Поскольку ввод является неконтролируемым, вы не можете гарантировать, что ввод будетOptionalЭтоnull. Это прямо противоречитOptionalнамерение. Поэтому попробуйте использовать в выраженияхOptionalили используйте его в возвращаемом значении, а не в параметре методаOptional.

6. Резюме

Да, сегодняOptionalОбъяснять. отOptionalдизайн был предназначен для его обычного подхода. мы тоже правыOptionalсуществуетJava 9Новые API в . Кроме тогоOptionalЭто не панацея, только разумное использование может сыграть на руку. Надеюсь, сегодняшняя статья будет вам полезна.

关注公众号:Felordcn获取更多资讯

Личный блог: https://felord.cn