введение
NPE (NullPointerException) является наиболее распространенным исключением в программах отладки. У Google много обсуждений о том, должен ли метод возвращать NULL или новый пустой объект.
В начале статьи давайте сначала поговорим о проблеме NPE. Проблема NPE - это NullPointerException, с которым мы часто сталкиваемся в разработке. Предположим, у нас есть два класса, и их диаграмма класса UML показана на следующем рисунке
В этом случае есть следующий код
user.getAddress (). getProvince ();
Этот способ написания может сообщать о NullPointerException, когда пользователь нулевой. Чтобы решить эту проблему, принят следующий метод написания
if (user! = null) {адрес Адрес = user.getAddress (); if (address! = null) {string province = address.getprovince (); }}Этот стиль письма относительно уродлив. Чтобы избежать вышеуказанного уродливого стиля письма, уродливый дизайн становится элегантным. Java8 предоставляет необязательный класс для оптимизации этого метода написания, а следующий текстовый раздел будет подробно объяснен.
API введение
Позвольте мне сначала представить API. В отличие от других статей, в этой статье используется метод аналогии и объединяет исходный код. В отличие от других статей, каждый список API делает людей неспособными найти ключевые моменты.
(1) Необязательно (значение t), empty (), of (значение t), ofnullable (значение t)
Эти четыре функции имеют корреляции, поэтому они помещаются в группу для памяти.
Позвольте мне сначала объяснить, что необязательное (значение t), то есть конструктор, является личным разрешением и не может быть вызвано извне. Другие три функции являются публичными разрешениями для нас, чтобы позвонить. Затем, сущность необязательного состоит в том, чтобы хранить реальную ценность внутри, и при строительстве непосредственно оценивается, является ли ее ценность пустой. Хорошо, это все еще довольно абстрактно. Непосредственно загрузите исходный код необязательного конструктора (значение t), как показано на рисунке ниже
Тогда исходный код (значение t) выглядит следующим образом
public static <t> необязательный <t> of (t value) {return new Необязательный <> (value); } Другими словами, конструктор называется внутренне функцией (значение). Основываясь на исходном коде конструктора, мы можем сделать два вывода:
(1) Когда значение значения пустое, все еще будет сообщено о нулевой точке.
(2) Необязательный объект, построенный функцией (значение (t), может быть построен нормально, когда значение значения не является пустым.
Кроме того, необязательный класс также поддерживает объект со значением NULL, вероятно, вроде следующего
Общественный окончательный класс необязательный <t> {// Опустить ...... частный статический окончательный окончательный необязательный <?> empty = new Необязательный <> (); private необязательный () {this.value = null; } // Опустить ... public static <t> необязательный <t> empty () {@suppresswarnings ("unchecked") необязательно <t> t = (необязательно <t>) пусто; возврат t; }} Тогда функция ement () состоит в том, чтобы вернуть пустой объект.
Ну, так много подготовки было заложено. Можно сказать, что of ofnullable (значение t) имеет функцию, и исходный код добавляется.
public static <t> необязательный <t> ofnullable (t value) {return value == null? empty (): of (value); } Ну, каждый должен понять, что это значит. Разница по сравнению со значением) состоит в том, что когда значение значения является нулевым, (значение t) будет сообщать о нулевой точке; Ofnullable (значение t) не будет выбросить исключение, оказалось, (значение t) непосредственно возвращает пустой объект.
Означает ли это, что мы только используем нулевую функцию вместо функции в нашем проекте?
Нет, если что -то существует, то это, естественно, будет иметь ценность. Когда мы работаем, мы не хотим скрывать NullPointerException. Вместо этого вам необходимо немедленно сообщить, и в этом случае использовать функцию. Но я должен признать, что действительно мало таких сцен. Блогер использовал эту функцию только в написании тестовых примеров Junit.
(2) Orelse (T other), Orelseget (поставщик <? Extens T> ore) и Orelsethrow (поставщик <? Extends x> ExceptionsUplier)
Эти три функции запоминаются в группе и вызываются, когда значение, передаваемое конструктором, является нулевым. Использование Orelse и Orelseget заключается в следующем. Когда значение является нулевым, дается значение по умолчанию:
@Testpublic void test () {user user = null; user = необязательный. Ofnullable (пользователь) .orelse (createUser ()); user = необязательный. Ofnullable (user) .orelseget ((() -> createUser ()); } public user createUser () {user user = new user (); user.setName ("Zhangsan"); вернуть пользователь;} Разница между этими двумя функциями: когда пользовательское значение не является нулевым, функция Orelse по -прежнему выполнит метод createUser (), в то время как функция OrelSeget не выполнит метод CreateUser (), поэтому вы можете проверить его самостоятельно.
Что касается OrelSethrow, когда значение является нулевым, исключение выброшено напрямую. Использование выглядит следующим образом
User user = null; необязательный. Ofnullable (user) .orelsethrow (()-> new Exception («пользователь не существует»));
(3) Map (function <? Super T ,? Extends u> Mapper) и Flatmap (function <? Super T, необязательный <u >> Mapper)
Эти две функции размещаются в наборе памяти, и эти две функции выполняют работу преобразования значений.
Непосредственно загрузить исходный код
public final Class необязательный <t> {// Опустить ...... public <u> Необязательный <u> map (function <? Super T ,? extends u> mapper) {objects.requirenonlull (mapper); if (! ispresent ()) return yate (); else {return optainAl.ofnullable (mapper.apply (value)); }} // Опустить ... public <u> Необязательный <u> flatmap (function <? Super T, необязательный <u >> mapper) {objects.requirenonlull (mapper); if (! ispresent ()) return yate (); else {return objects.requirenonnull (mapper.apply (value)); }}} Нет разницы между этими двумя функциями в теле функции. Единственная разница - это параметр записи. Тип параметра входа, принятый функцией карты, является функцией <? Супер Т, Extends u>, в то время как тип параметра входа типа Flaymap - это функция <? Super T, необязательный <u>>.
С точки зрения конкретного использования, для карты:
Если структура пользователя выглядит следующим образом
Пользователь открытого класса {Private String name; public String getName () {return name; }}В настоящее время метод написания имени выглядит следующим образом
String city = необязательно.
Для карты:
Если структура пользователя выглядит следующим образом
Пользователь открытого класса {Private String name; публичный необязательный <string> getName () {return optainAl.ofnullable (name); }}В настоящее время метод написания имени выглядит следующим образом
String city = необязательно.
(4) iSpresent () и ifpresent (потребитель <? Super T> потребитель)
Соберите эти две функции и запомните их. Ispresent означает определение того, является ли значение пустым, а если предложение означает выполнение некоторых операций, когда значение не является пустым. Исходные коды этих двух функций следующие
открытый окончательный класс необязательный <t> {// Опустить ...... public boolean ispresent () {return value! = null; } // Опустить ... public void ifpresent (Consumer <? Super T> Consumer) {if (value! = Null) Conmerce.accep (value); }}Это требует дополнительного объяснения, не
if (user! = null) {// todo: сделать что -нибудь}Написано
Пользователь пользователя = необязательный.ofnullable (user); if (intocial.ispresent ()) {// todo: сделать что -нибудь} Из -за этого структура кода все еще уродлива. Блогер даст правильный метод написания позже
Что касается IfPresent (Consumer <? Super T> Consumer), использование также очень простое, как показано ниже
Необязательный. ОФАНАБЛИЦА (пользователь) .ifpresent (u-> {// todo: сделать что-нибудь});(5) Фильтр (предикат <? Super t> предсказание)
Без лишних слов, просто загрузите исходный код
публичный окончательный класс необязательный <t> {// Опустить ...... Objects.Requirenonnull (Predicate); if (! Ispresent ()) вернуть это; else return Predict.test (значение)? это: empty ();} Метод фильтра принимает предикат для фильтрации значений, содержащихся в необязательных. Если включенные значения соответствуют условиям, то необязательные все равно будут возвращены; В противном случае, опциональный. EMPTY будет возвращен.
Использование выглядит следующим образом
Необязательный <user> user1 = необязательный.офналлебельный (user) .filter (u -> u.getName (). Length () <6);
Как показано выше, если длина имени пользователя меньше 6, то верните. Если он больше 6, возвращается пустой объект.
Практическое использование
Пример 1
В методе функции
Предыдущее письмо
public String getCity (пользователь пользователя) Throws Exception {if (user! = null) {if (user.getAddress ()! = null) {Addch Address = user.getAddress (); if (address.getCity ()! = null) {return address.getCity (); }}} бросить новую экспертизу ("ошибка значения"); }Метод написания Java8
public String getCity (пользователь пользователя) Throws Exception {return optainAl.ofnullable (user) .map (u-> u.getAddress ()) .map (a-> a.getCity ()) .orelsethrow (()-> Новое исключение («ошибка извлечения»);};};};};};};};Пример 2
Например, в основной программе
Предыдущее письмо
if (user! = null) {dosomething (user);}Метод написания Java8
Необязательный. ОФАНАЛЬНЫЙ (пользователь) .ifpresent (u-> {dosomething (u);});Пример 3
Предыдущее письмо
public user getUser (пользователь пользователя) выбрасывает Exception {if (user! = null) {string name = user.getName (); if ("zhangsan" .equals (name)) {return user; }} else {user = new user (); user.setName ("Zhangsan"); вернуть пользователь; }}Метод написания Java8
Общедоступный пользователь GetUser (пользователь пользователя) {return optainAl.OfNullable (user) .filter (u-> "Zhangsan" .equals (u.getName ())) .orelseget (()-> {user user1 = new user (); user1.setname ("zhangsan"); return user1;});};};};};};};};};};};Другие примеры не будут перечислены один за другим. Тем не менее, блоггер считает, что использование этого программирования цепочки на самом деле элегантно в коде. Тем не менее, логика не так очевидна, а читабельность уменьшается. Мы используем его в соответствии с ситуацией в проекте.
Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.