краткое содержание
Когда я был свободен, мне понадобилось время, чтобы выучить Groovy и Scala, бегущие на JVM, и обнаружил, что они обрабатывают ноль гораздо более осторожно, чем более ранние версии Java. В Java 8, опционально дает очень элегантное решение для функционального программирования нулевой обработки. Эта статья объяснит давнюю плохую обработку NULL в Java, а затем введет использование необязательного для реализации функционального программирования Java.
Нолл, который беспокоил нас в те годы
В мире Java есть легенда: только когда вы действительно понимаете исключение Null Pointer, можете ли вы считать квалифицированным разработчиком Java. В нашей карьере персонажа Java мы будем встречаться с различной нулевой обработкой каждый день. Мы можем писать коды, как следующие многократно каждый день:
if (null! = obj1) {if (null! = obje2) {// сделать что -нибудь}}Если у вас есть небольшое видение, Javaer сделает несколько красивых вещей и найдет способ судить NULL:
Boolean checknotnull (Object obj) {return null == obj? Неверно: Верно; } void do () {if (checknotnull (obj1)) {if (checknotnull (obj2)) {// do Что -то}}}Затем возникает вопрос: если нулевой представляет собой пустую строку, что означает "" ""?
Тогда инерционное мышление говорит нам: «и NULL являются пустыми строковыми кодами? Я просто обновил нулевое значение:
Boolean checknotblank (Object obj) {return null! = obj &&! "". equals (obj)? Верно: Неверно; } void do () {if (checknotblank (obj1)) {if (checknotnull (obj2)) {// do Что -то}}}Если у вас есть время, вы можете проверить, сколько кода вы написали в текущем проекте или в своем прошлом коде и что похоже на приведенный выше код.
Интересно, серьезно ли вы думали о вопросе: что означает нулевая?
Напомним, сколько раз мы сталкивались с java.lang.nullpointerexception исключения в нашей предыдущей карьере грамминга? NullPointerException - это исключение уровня RuntimeException, которое не нужно захватить. Если мы случайно обрабатываем это, мы часто видим различные выходы стека исключений, вызванные NullPointerException в производственном журнале. И на основе этой информации о стеке исключений мы вообще не можем найти причину проблемы, потому что это не то место, где было брошено NullPointerException, что вызвало проблему. Мы должны идти глубже, чтобы выяснить, где был сгенерирован этот нуль, и журналы часто не могут отслеживать в это время.
Иногда еще более трагично, что места, где производятся нулевые значения, часто не в нашем собственном коде проекта. Это имеет более смущающий факт - когда мы называем различные сторонние интерфейсы разного качества, трудно сказать, возвращает ли интерфейс случайно ...
Вернитесь к предыдущей когнитивной проблеме NULL. Многие Javaers считают, что NULL означает «ничего» или «ценность не существует». Согласно этому инерционному мышлению, наша логика кода: вы называете мой интерфейс и возвращаете соответствующее «значение» в соответствии с параметрами, которые вы мне даете. Если это условие не может найти соответствующее «значение», то, конечно, я верну вам нуль, что нет «вещи». Давайте посмотрим на следующий код, который написан в очень традиционном и стандартном стиле кодирования Java:
класс MyEntity {int id; String name; String getName () {return name; / System.out.println (myentity.getName ()); } private getMyEntity (boolean issuc) {if (issuc) {return new myEntity (); } else {return null; }}}Этот фрагмент кода очень прост, и ежедневный бизнес -код определенно намного сложнее, чем этот, но на самом деле большое количество наших кодов Java написано в соответствии с этой рутиной. Люди, которые знают, как использовать товары, могут сразу же видеть, что в конце концов они определенно бросят NullpointerException. Однако, когда мы пишем бизнес -код, мы редко думаем о том, чтобы справиться с этим возможным нулевым (возможно, документ API был написан очень четко и в некоторых случаях вернете NULL, но убедитесь, что вы будете тщательно прочитать документ API, прежде чем начать писать код?), Пока мы не достигли определенного этапа тестирования, NullPointerExcept
// Тест MainBublic Class {public static void main (string [] args) final myEntity myEntity = getMyEntity (false); if (null! = myentity) {System.out.println (myentity.getName ()); } else {System.out.println ("error"); }}}Тщательно подумайте о последних нескольких годах, мы все это сделали? Если некоторые нулевые проблемы не могут быть обнаружены до фазы тестирования, то сейчас проблема - сколько нулей не обрабатывается должным образом в этих сложных и хорошо структурированных бизнес -кодах?
Зрелость и строгость проекта часто можно увидеть при работе с NULL. Например, гуава дал элегантный метод нулевой обработки перед JDK1.6, который показывает, насколько глубоки навыки.
Призрачные нули не позволяют нам прогрессировать
Если вы Javaer, специализирующийся на традиционном объектно-ориентированном развитии, вы можете быть использованы с различными проблемами, вызванными NULL. Но много лет назад великий Бог сказал, что NULL - это яма.
Тони Холл (разве ты не знаешь, кто этот парень? Иди, проверь самостоятельно) однажды сказал: «Я называю это моей ошибкой в миллиард долларов. Это было изобретение нулевой ссылки в 1965 году. Я не смог устоять перед искушением поставить нулевую ссылку, просто потому, что это было так легко реализовать». (Общее значение таково: «Я называю это изобретением Null бесценной ошибкой. Потому что в пустыне компьютеров в 1965 году пустые ссылки были слишком легко реализовать, поэтому я не смог устоять перед искушением изобретать нулевый указатель».).
Тогда давайте посмотрим, какие другие проблемы будут введены в норму.
Проверьте следующий код:
String address = person.getCountry (). GetProvince (). GetCity ();
Если вы играли на некоторых функциональных языках (Haskell, Erlang, Clojure, Scala и т. Д.), Вышеуказанное - очень естественный способ письма. Конечно, приведенный выше метод написания может быть реализован с использованием Java.
Но для того, чтобы отлично справиться со всеми возможными нулевыми исключениями, мы должны изменить эту элегантную парадигму программирования функции на это:
if (человек! = null) {country = person.getCountry (); if (country! = null) {провинция провинция = country.getprovince (); if (провинция! = null) {address = province.getCity (); }}}В одно мгновение высококачественное функциональное программирование Java8 вернулось 10 лет назад. Такие вложенные суждения все еще тривиальны, увеличивают количество кодекса и не являются неотъемлемыми. Скорее всего, это произойдет: в течение большей части времени люди забудут судить о том, что может произойти, даже пожилые люди, которые писали код в течение многих лет, не являются исключением.
Вышеупомянутый раздел нулевой обработки, которая является вложенным слоем за слоем, также является частью традиционной Java, критикованной в течение длительного времени. Если вы используете ранние версии Java в качестве языка просветления, этот запах get-> Если null-> return повлияет на вас в течение длительного времени (помните в иностранном сообществе, которое называется: ориентированное на организацию развитие).
Использование необязательного для реализации функционального программирования Java
Ладно, после разговора обо всех видах проблем, мы можем войти в новую эру.
Задолго до запуска версии Java SE 8, другие аналогичные языки функциональной разработки имели свои различные решения. Вот код Groovy:
String version = computer? .GetSoundCard () ?. getUSB ()?
Haskell использует идентификатор класса, возможно, для обработки нулевых значений. Scala, известная как многопарадигм, языка разработки, предоставляет вариант [T], который похож на, возможно, для обертывания и обработки NULL.
Java8 представляет java.util.optional <t> для решения нулевой проблемы функционального программирования. Идеи обработки дополнительных <T> аналогичны идеям Haskell и Scala, но есть некоторые различия. Давайте посмотрим на следующий пример кода Java:
открытый тест класса {public static void main (string [] args) {final String text = "Hallo World!"; Необязательный. ОФАНАЛЬНЫЙ (Текст) // Показать для создания необязательного shell.map (test :: print) .map (test :: print) .ifpresent (system.out :: println); Необязательно. } // Печать и перехват строки после Str [5] Private Static String Print (String Str) {System.out.println (str); вернуть Str.Substring (6); }} // consol output // num1: hallo world! // num2: world! // num3: // num4: hallo world!(Вы можете скопировать приведенный выше код в свой IDE, при условии, что JDK8 должен быть установлен.)
Два дополнительных опционов создаются в приведенном выше коде, а реализованные функции в основном одинаковы. Они оба используют необязательную в качестве строковой оболочки для усечения строки. Когда во время обработки встречается нулевое значение, обработка больше не будет продолжаться. Мы можем обнаружить, что после того, как S-> NULL появится во втором необязательном, последующее IFPRENT больше не будет выполняться.
Обратите внимание на вывод // num3:, это означает, что символ «» является выводом, а не ноль.
Необязательно предоставляет богатые интерфейсы для обработки различных ситуаций, таких как изменение кода на:
открытый тест класса {public static void main (string [] args) {final String text = "Hallo World!"; System.out.println (строчный (текст)); // Метод один нижний регистр (null, system.out :: println); // Метод второй} частная статическая строка нижняя строка (String str) {return optunity.ofnullable (str) .map (s -> s.tolowercase ()). Map (s-> s.replace ("World", "java") } частная статическая пустота нижняя часть (String Str, Consumer <string> Consumer) {consumer.accep (строчный (str)); }} // output // hallo java! // nanТаким образом, мы можем динамически обработать строку. Если значение считается нулевым в любое время, мы используем Orelse для возврата предустановленного дефолта "NAN".
В целом, мы можем обернуть любую структуру данных в необязательную, а затем обрабатывать ее функционально, не беспокоясь о нулевых условиях, которые могут появиться в любое время.
Давайте посмотрим, как Person.getCountry (). GetProvince (). GetCity (), упомянутое ранее, не требует куча IFS, чтобы справиться с этим.
Первый метод состоит в том, чтобы не изменить предыдущую сущность:
Импорт java.util.optional; открытый тест класса {public static void main (string [] args) {system.out.println (optactal.ofnullable (new Person ()) .map (x-> x.country) .map (x-> x.provinec) .map (x-> x.city) .map (x-> x.name). .orelse ("unkonwn")); }} класс Person {Country Country;} Class Country {Province provisionec;} Class Province {City City;} Class City {String name;}Здесь необязательно используется, когда оболочка возвращается каждый раз. Если определенная позиция вернет NULL, вы получите "unkonwn".
Второй метод состоит в том, чтобы определить все значения в необязательных:
import java.util.optional; открытый тест класса {public static void main (string [] args) {system.out.println (new Person () .country.flatmap (x -> x.provinec) .flatmap (province :: getCity) .flatmap (x -> x.name) .orelse (unkonwn); }} класс Person {необязательный <Country> country = intociate.empty ();} class country {необязательный <vince> provisionc;} Class Province {необязательный <Сити> City; Необязательно <tity> getCity () {// for :: return City; }} класс City {необязательный <string> name;}Первый метод может быть гладко интегрирован с существующими джабеанами, сущностью или POJA без каких-либо изменений и может быть легче интегрирован в сторонние интерфейсы (например, пружинные бобы). Рекомендуется использовать первый необязательный метод в качестве основного метода. В конце концов, не все в команде могут понять цель каждого Get/Set с необязательным.
Опционально также предоставляет метод фильтра для фильтрации данных (фактически, интерфейсы в стиле потока в Java 8 предоставляют методы фильтра). Например, в прошлом мы судили, что значение существовала и сделана соответствующая обработка:
if (провинция! = null) {City City = Province.getCity (); if (null! = city && "guangzhou" .equals (city.getname ()) {System.out.println (city.getName ());} else {System.out.println ("unkonwn");}}}}}}}}}}}}Теперь мы можем изменить его на
Необязательный. ОФАНАБЛИЦА (провинция) .map (x-> x.city) .filter (x-> "guangzhou" .equals (x.getname ())) .map (x-> x.name) .orelse ("unkonw");На этом этапе функциональное введение программирования завершено с использованием необязательного. В дополнение к упомянутым выше методам, необязательно также предоставляет методы, основанные на больших потребностях, Orelseget, Orelsethrow и т. Д. Orelseget выставит нулевое исключение указателя из-за нулевого значения, и OrelSethrow будет выбросить определенное пользовательское исключение, когда возникает нулевое. Вы можете просмотреть документацию API, чтобы узнать больше обо всех методах.
Написано в конце
Необязательно - это только вершина айсберга функционального программирования Java. Необходимо объединить такие функции, как лямбда, поток и функция, чтобы по -настоящему понять эффективность функционального программирования Java8. Первоначально я хотел представить некоторые необязательные принципы исходного кода и эксплуатацию, но по себе необязательно имеет очень мало кода и не очень много интерфейса API. Если вы внимательно подумаете об этом, нечего сказать, и вы опустите это.
Хотя необязательно элегантен, я лично чувствую, что есть некоторые проблемы с эффективностью, но это еще не было проверено. Если у кого -нибудь есть данные, пожалуйста, дайте мне знать.
Я не «сторонник функционального программирования». С точки зрения менеджеров команд, для каждой небольшой сложности обучения увеличивается, стоимость использования персонала и взаимодействие команды будет выше. Как и в легенде, у LISP может быть в тридцать раз меньше кода, чем C ++, и он более эффективен в разработке, но если внутренняя обычная ИТ -компания действительно использует LISP для выполнения проектов, куда идти и сколько стоит, чтобы эти парни использовали LISP?
Но я настоятельно рекомендую всем изучать и понять идеи функционального программирования. Особенно разработчики, которые раньше были захвачены Java и до сих пор не знают, что принесет Java8, Java8 - хорошая возможность. Также рекомендуется представить новые функции Java8 в текущий проект. Команда, которая сотрудничает в течение долгого времени, и древний язык программирования, нуждается в постоянном внедрении новой жизненной силы, в противном случае вы отступите, если не продвигаетесь.
Выше приведено коллекция дополнительной информации Java. Мы будем продолжать добавлять соответствующую информацию в будущем. Спасибо за поддержку этого сайта!