что значит null в java
10 способов эффективно справиться с Null в Java
Авторизуйтесь
10 способов эффективно справиться с Null в Java
Когда я только начал программировать на Java, Null очень быстро стал моим главным врагом. Сейчас я могу с уверенностью сказать, что битва между мной и Null с успехом завершилась. Большинство NullPointerExceptions случаются по неосторожности, и, чтобы помочь вам научиться справляться с ними, я подготовил небольшой список того, что я обычно делаю, когда встречаюсь Null.
Не усложняйте
Используйте методы Objects в качестве предикатов Stream
Хотя использование Objects.isNull и Objects.nonNull не очень хорошо подходит при обычной проверки на Null, однако они отлично подойдут для использования в потоках.
Никогда не передавайте Null в качестве аргумента
Данных проблем можно избежать, если никогда не использовать Null в качестве аргумента функции.
Проверяйте аргументы публичных API
Конечно, вы и ваша команда можете придерживаться принципа — «никогда не использовать Null в качестве аргумента функции», но что, если у вас есть свой публичный API, и его пользователи даже не слышали о таком принципе? Поэтому лучше всегда проверять на корректность аргументы, передаваемые в ваш API.
Эффективно используйте Optional
Возвращайте пустые коллекции вместо Null
Optional не подходит для полей
Согласно правилам инкапсуляции вы должны иметь полный контроль над значениями полей, включая Null. С другой стороны, что если мы сделаем так, что поля могут и не иметь значений? Тогда это приведет к нескольким проблемам:
Вывод: не используйте Optional с полями.
Используйте исключения вместо Null
Если что-то пошло не так: всегда используйте исключения, вместо того, чтобы возвращать Null.
Тестируйте свой код
Тестирование — хороший способ обнаружить NPE и исправить их. Поэтому никогда не стоит выпускать проект, предварительно не протестировав его.
Двойная проверка
Каждый раз, когда вы предполагаете, что какое-то выражение не может оказаться Null — дважды проверьте ваши выводы. Используйте документацию к API, спросите коллег, задайте вопрос на Stack Overflow. И всегда помните, что лучше перестраховаться, чем потом возиться с Null.
Что такое null в Java?
Является ли null экземпляром чего-либо?
В чем набор null принадлежит?
Как он представлен в памяти?
ОТВЕТЫ
Ответ 1
Является ли null экземпляром чего-либо?
15.20.2 Оператор сравнения типов instanceof
JLS 4.1 Виды типов и значений
Как сказано выше в JLS-цитате, на практике вы можете просто притвориться, что это «просто специальный литерал, который может быть любого ссылочного типа».
В Java null == null (это не всегда происходит на других языках). Заметим также, что по контракту он также обладает этим специальным свойством (от java.lang.Object ):
public boolean equals(Object obj)
Это также значение по умолчанию (для переменных, которые есть у них) для всех типов ссылок:
JLS 4.12.5 Начальные значения переменных
Как это используется, меняется. Вы можете использовать его, чтобы включить то, что называется ленивой инициализацией полей, где поле будет иметь начальное значение null до тех пор, пока оно фактически не будет использовано, где оно будет заменено на «реальное» значение (которое может быть дорогостоящим для вычисления).
Существуют и другие виды использования. Возьмем настоящий пример из java.lang.System :
Это очень распространенный шаблон использования: null используется для обозначения несуществующего объекта.
Вот еще один пример использования, на этот раз из java.io.BufferedReader :
public String readLine() throws IOException
Возьмем еще один пример, на этот раз из java.util.Map :
Вообще говоря, null используются как специальное значение для обозначения:
В Java? Ничего из вас. И это лучше всего сохранилось.
Есть ли null хорошая вещь?
Это огромная тема сама по себе, поэтому ее лучше обсудить как ответ на другой вопрос.
Я закончу это цитатой самого изобретателя null C.A.R Hoare (для быстрой сортировки):
Я называю это своей ошибкой в миллиард долларов. Это было изобретение справочника null в 1965 году. В то время я разрабатывал первую всеобъемлющую систему типов для ссылок в объектно-ориентированном языка (ALGOL W). Моя цель состояла в том, чтобы гарантировать, что все использование ссылок должно быть абсолютно безопасным, причем проверка выполняется автоматически компилятором. Но я не мог удержаться от соблазна поставить ссылку null просто потому, что ее было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, вызвали миллиард долларов боли и ущерба за последние сорок лет.
Видео этой презентации идет глубже; это рекомендуемые часы.
Ответ 2
Является ли null экземпляром чего-либо?
Он является единственным и единственным членом нулевого типа, где нулевой тип определяется следующим образом:
См. выше. В некоторых контекстах null используется для обозначения «no object» или «unknown» или «unavailable», но эти значения являются специфичными для приложения.
Это специфичная реализация, и вы не сможете увидеть представление null в чистой программе Java. (Но null представляется как нулевой машинный адрес/указатель в большинстве, если не во всех реализациях Java.)
Ответ 3
Что такое null?
Является ли null экземпляром чего-либо?
Нет, как ничто. Это не может быть примером какой-либо вещи.
Какой набор имеет значение null?
Нет никакого набора
Как он представлен в памяти?
Если некоторые ориентиры указывают на это как:
В памяти кучи некоторое пространство присваивается новому созданному объекту. И o укажет на выделенное место в памяти.
Это означает, что теперь o не будет указывать на это пространство памяти объекта.
Ответ 4
Нет, это не экземпляр ничего, instanceof всегда будет false.
Ответ 5
Также, возможно, посмотрите
Ответ 6
в зависимости от параметров модели компилятора и модели памяти. NULL не является, строго говоря, частью самого C/С++.
В Java ™ «null» не является ключевым словом, а является специальным литералом типа null. Его можно использовать для любого ссылочного типа, но не для любого примитивного типа, такого как int или boolean. Нулевой литерал необязательно имеет значение 0. И невозможно применить к типу null или объявить переменную этого типа.
Ответ 7
Null не является экземпляром любого класса.
Однако вы можете присвоить значение null переменным любого типа (объекта или массива):
Ответ 8
Ответ 9
Ответ 10
Представление байткода
null имеет прямую поддержку JVM: для ее реализации используются три команды:
Глава 6 «Набор инструкций виртуальной машины Java» затем описывает эффекты null в других инструкциях: он выдает NullPointerException для многих из них.
2.4. «Типы ссылок и значения» также упоминает null в общих терминах:
Базовое значение также может быть специальной нулевой ссылкой, ссылкой на какой-либо объект, который будет обозначаться здесь нулем. Первоначальная нулевая ссылка не имеет типа времени выполнения, но может быть применена к любому типу. Значение по умолчанию для ссылочного типа равно null.
Ответ 11
Интересным способом увидеть null в java, на мой взгляд, является его просмотр как нечто, что НЕ означает отсутствие информации, а просто как буквальное значение, которое может быть присвоено ссылке любого типа. Если вы думаете об этом, если обозначить отсутствие информации, то для a1 == a2 быть истинным не имеет смысла (в случае, если им было присвоено значение null), поскольку они действительно могли бы указывать на ЛЮБОЙ объект (мы просто не знаю, на какие объекты они должны указывать). Кстати null == null возвращает true в java. Если java, например. будет похоже на SQL: 1999, тогда null == null вернет неизвестный (логическое значение в SQL: 1999 может принимать три значения: true, false и неизвестно, но на практике неизвестно реализовано как null в реальных системах). http://en.wikipedia.org/wiki/SQL
Ответ 12
В Java существуют две основные категории типов: примитивная и ссылка. Переменные, объявленные значения хранилища примитивного типа; переменные, объявленные ссылками хранилища ссылочного типа.
В этом случае оператор инициализации объявляет переменные «x». «x» хранит ссылку на String. Здесь null. Прежде всего, null не является допустимым экземпляром объекта, поэтому для него не выделяется память. Это просто значение, указывающее, что ссылка на объект в настоящее время не ссылается на объект.
Ответ 13
Короткий и точный ответ, который формально отвечает на все ваши вопросы из JLS:
Тип null имеет одно значение, нулевую ссылку, представленную null literal null, который формируется из символов ASCII.
Нулевой литерал всегда имеет нулевой тип.
Выделяется только ссылка типа, присвоенного нулевому значению. Вы не присваиваете ссылку на значение (объект). Такое распределение специфично для JVM, сколько ссылок потребуется и в какой области памяти будет выделено.
Ответ 14
null в Java аналогичен/аналогичен nullptr в С++.
Такая же программа в Java:
Теперь вы понимаете из кодов выше, что является нулевым в Java? Если нет, то я рекомендую вам изучить указатели на C/С++, а затем вы поймете.
Обратите внимание, что в C, в отличие от С++, nullptr является undefined, но вместо него используется NULL, который также может использоваться и на С++, но в С++ nullptr более предпочтителен, чем просто NULL, потому что NULL в C всегда связанный с указателями, и что он, поэтому в С++ суффикс «ptr» был добавлен к концу слова, а также все буквы теперь имеют строчные буквы, но это менее важно.
В С++ вы можете использовать указатели и значение nullptr для необязательных членов/переменных, то есть член/переменная, которая не имеет значения, и если она не имеет значения, то она равна nullptr, поэтому как null в Например, Java может использоваться.
Что такое null в Java?
Is null экземпляр чего-либо?
что значит null принадлежит?
как он представлен в памяти?
14 ответов
является ли null экземпляром чего-либо?
15.20.2 Тип Оператора Сравнения instanceof
к какому набору принадлежит’ null’?
JLS 4.1 виды типов и значений
как говорится в приведенной выше цитате JLS, на практике вы можете просто притвориться, что это»просто специальный литерал, который может быть любого ссылочного типа».
В Java, null == null (это не всегда так на других языках). Обратите внимание также, что по договору он также имеет это специальное свойство (от java.lang.Object ):
public boolean equals(Object obj)
это тоже значение по умолчанию (для переменных, которые имеют их) для всех ссылочных типов:
JLS 4.12.5 начальные значения переменных
как это зависит. Вы можете использовать его, чтобы включить то, что называется ленивая инициализация полей, где поле будет иметь начальное значение null пока он фактически не используется, где он заменяется «реальным» значением (которое может быть дорогостоящим для вычисления).
есть и другие использует. Возьмем реальный пример из java.lang.System :
это очень распространенный шаблон использовать: null используется для обозначения несуществования объекта.
вот еще один пример использования, на этот раз из java.io.BufferedReader :
public String readLine() throws IOException
возвращает: A String содержит содержимое строки, не включая символы завершения строки, или null если достигнут конец потока.
здесь readLine() вернутся instanceof String для каждой строки, пока наконец не возвращает null чтобы обозначить конец. Это позволяет обрабатывать каждую строку следующим образом:
давайте возьмем другой пример, на этот раз с java.util.Map :
возвращает значение, к которому сопоставлен указанный ключ, или null Если эта карта не содержит отображения для ключа.
здесь мы начинаем видеть, как с помощью null может усложнить ситуацию. Первое утверждение гласит, что если ключ не сопоставлен, null возвращается. Второе утверждение говорит, что даже если ключ сопоставлен, null can и будет возвращенный.
вы можете прочитать остальную часть API и найти, где и как есть. Имейте в виду, что они не всегда лучшие практики примеры.
вообще говоря, null используются в качестве специального значения для обозначьте:
как это представлено в памяти?
В Java? Не твое дело. И так будет лучше.
Is null хорошая вещь?
это теперь пограничный субъективный. Некоторые говорят, что null вызывает много ошибок программиста, которых можно было бы избежать. Некоторые говорят, что на языке, который ловит NullPointerException как Java, хорошо использовать его, потому что вы будете быстро терпеть неудачу при ошибках программиста. Некоторые люди избегают null С помощью Null шаблон объекта, etc.
это огромная тема сама по себе, поэтому лучше всего обсудить ее как ответ на другой вопрос.
я называю это своей миллиардной ошибкой. это было изобретение null ссылка в 1965 году. В то время я разрабатывал первую комплексную систему типов для ссылок на объектно-ориентированном языке (ALGOL W). Моя цель состояла в том, чтобы убедиться, что все использование ссылок должно быть абсолютно безопасным, а проверка выполняется автоматически компилятором. Но я не мог устоять перед искушением вставить:—2—> ссылка, просто потому, что это было так легко осуществить. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.
на видео-презентации идет глубже; это рекомендуемые часы.
является ли null экземпляром чего-либо?
к какому набору принадлежит ‘null’?
это один и единственный член типа null, где тип null определяется следующим образом:
» существует также специальный тип null, тип выражения null, который не имеет имени. Поскольку тип null не имеет имени, невозможно объявить переменную типа null или привести к типу null. Ссылка null является единственным возможным значением выражения типа null. Нулевая ссылка всегда может быть приведена к любому ссылочному типу. На практике программист может игнорировать тип null и просто притворяться, что null является просто специальным литерал, который может быть любого ссылочного типа.» JLS 4.1
см. выше. В некоторых контекстах, null используется для обозначения «нет объекта» или «неизвестно» или «недоступно», но эти значения специфичны для приложения.
это конкретная реализация, и вы не сможете увидеть представление null в чистом Java программа. (Но null представлен как нулевой адрес / указатель машины в большинстве, если не во всех реализациях Java.)
что такое null?
является ли null экземпляром чего-либо?
нет, поскольку это ничто, это не может быть экземпляром какой-либо вещи.
к какому набору принадлежит null?
нет никакого набора
как он представлен в памяти?
Если некоторые ориентиры к нему, как:
в памяти кучи некоторое пространство, назначенное new созданный объект. И o укажет на это место в памяти.
Это означает, что теперь не будет указывать, что область памяти объекта.
нет, это не экземпляр чего-либо, instanceof всегда будет ложным.
ключевое слово null является литералом, представляющим пустую ссылку, тот, который не относится ни к одному объекту. null-значение по умолчанию для переменных ссылочного типа.
также возможно посмотреть
в зависимости от параметров компилятора и модели памяти. NULL не является, строго говоря, частью самого C / C++.
null не является экземпляром какого-либо класса.
однако вы можете назначить null переменным любого типа (объекта или массива):
null является специальным значением, это не экземпляр ничего. По очевидной причине этого не может быть instanceof ничего.
представление байт-кода
в Java null имеет прямую поддержку JVM: для ее реализации используются три инструкции:
Глава 6 «Набор Инструкций Виртуальной Машины Java» затем упоминает последствия null на других инструкции: он бросает!—9—> для многих из них.
2.4. «Ссылочные типы и значения» также упоминает null в общих чертах:
ссылочное значение также может быть специальной нулевой ссылкой, ссылкой на объект no, которая будет обозначаться здесь null. Нулевая ссылка изначально не имеет типа времени выполнения, но может быть приведена к любому типу. По умолчанию значение типа null.
Учимся избегать null-значений в современном Java. Часть 1
Oct 12, 2020 · 11 min read
Null. Правила использования
В своем выступлении “Null References: The billion dollar mistake” (“Нулевые ссылки: ошибка на миллиа р д долларов”), Тони Хоар описывает реализацию нулевых ссылок в языках программирования ALGOL, что также по его словам стало ошибкой стоимостью в миллиард долларов. Такие авторитетные книги, как Clean Code: A Handbook of Agile Software Craftsmanship (“Чистый код: настольное руководство по гибкой разработке ПО”) рекомендуют использовать нуль как можно реже. В то же время в книге Bug Patterns in Java (“Шаблоны ошибок в Java”) проблемам, связанным с нулевыми значениями, посвящается аж целых три главы. Тема “What is a null pointer exception and how do I fix it” (“Что такое исключение нулевого значения и как его исправить”), обсуждаемая на Stack Overflow, набрала уже более 3 млн просмотров. Работа с нулевыми значениями и впрямь может вызвать немало сложностей.
Я не отношусь к тем, кто можем говорить лауреатам премии Тьюринга вроде Хоар, как проектировать языки программирования, но при этом все же не считаю null заведомо плохим. В этой и последующих статьях мы рассмотрим, что это вообще такое, когда стоит или не стоит эти значения использовать, а также, как их изящно обрабатывать.
В конкретно данной статье я поделюсь своими размышлениями об их использовании, а в следующей мы перейдем к рассмотрению практического применения некоторых методов работы с null, включая последние возможности Java 8.
Несмотря на то, что в центре нашего внимания будет именно Java, основные принципы и обсуждение должны охватывать объектно-ориентированные языки в целом. Текущая статья в первую очередь предназначена для менее опытных программистов и всех тех, кто испытывает сложности, сталкиваясь с null. Но, думаю, что даже бывалые разработчики смогут найти здесь для себя полезные приемы.
Чем опасен null?
Null — это особое значение, поскольку оно не ассоциируется ни с каким типом (можете смело проверить это инструкцией instanceof в отношении любого другого класса в JRE) и с радостью занимает место любого другого объекта в присвоениях переменных и вызовах методов. Именно в этом и кроются две основных его опасности:
В результате любое возвращаемое значение или объект параметра — это потенциальное исключение нулевого указателя (NPE), возникающее в случае неправильной обработки.
Будет ли в таком случае решением проверять каждое возвращаемое значение и параметр на null? Очевидно, что идея не очень. Во-первых, код будет загроможден проверками на null. Во-вторых, разработчики будут вынуждены тратить драгоценное время на поиск правильного способа обработки нулевых значений, которые никогда не возникнут, а проверки на null будут сбивать с толку других разработчиков.
Может тогда вообще никогда не присваивать значениям null? Тоже неудачное предположение. Если учесть тот факт, что в каждом языке программирования есть пустое значение ( nil, undefined, None, void и т.д.), то наличие общего значения, обозначающего отсутствие чего-либо, чрезвычайно полезно.
Ошибка в условии цикла while может породить бесконечный цикл в любой программе, но это не делает такие циклы плохими по природе. Аналогично будет неверным считать, что null всегда неуместен только из-за того, что его неправильное использование может привести к ошибкам. Null — это наиболее естественное значение для выражения конкретных вещей, но при этом очень неподходящее для выражения других. Компетентные разработчики должны уметь различать эти случаи. В следующем разделе я как раз перейду к объяснению этого.
Когда Null уместен, а когда нет
В этой части я рассмотрю сценарии, в которых null возвращается из методов и передается им, поясню несколько традиционных альтернатив (т.е. предшествующих Java 8) и приведу доводы в пользу уместности встроенного типа вроде null в некоторых случаях.
Возвращение null
Одной из основных идей ООП является моделирование принципов области бизнеса, в которой работает наше ПО. Для этого мы определяем классы, соответствующие данным принципам и их атрибутам. Если речь заходит об использовании нулевых значений, я считаю важным рассмотреть эти типы классов отдельно от остальных.
Сейчас я работаю над проектом электронной записи пациентов Columna, в котором у нас есть классы, представляющие элементы рабочего процесса больницы вроде пациентов, медикаментов, врачей, больничных отделений, госпитализаций и пр. При моделировании любой области возникают случаи, когда нам нужно допустить для определенного элемента отсутствие значения. Предположим, что у нас есть класс, представляющий госпитализацию с атрибутами, которые ее описывают: больничное отделение, куда помещается пациент, причина госпитализации, ее время и т.д. Аналогичным образом у нас может быть класс, который представляет пациента с набором атрибутов вроде имени и номера социального страхования. В любой момент времени пациент может быть госпитализирован или нет. Говоря более формально, у нас есть связь типа “имеет” с мощностью 0..1.
Представим метод, извлекающий из базы данных информацию о госпитализации данного пациента:
Что должен возвращать этот метод для не госпитализированного пациента, если не null? Есть ли для выражения этого более точное значение? Спорю, что нет.
Существует и много других сценариев, в которых объект области напрямую ассоциирован с необязательными значениями в качестве атрибутов. Объект, представляющий медикаменты, содержит такие значения, как название препарата, его форму, активность, действующее вещество и т.д. Однако разнообразие медикаментов чрезвычайно обширно, начиная от антибактериальных кремов и заканчивая чаями из каннабиса (оставим или на ромашку заменим?:)), следовательно не все атрибуты будут актуальны для каждого. И снова возвращение null для отсутствующего атрибута выглядит очевидным способом сообщить, что допускается отсутствие значения. Есть ли для этого лучшая альтернатива?
Некоторые выступают за использование так называемого шаблона проектирования Null Object вместо null. Главная его идея в реализации пустого класса с минимумом или вообще без функциональности, т.е. нулевого объекта, который можно использовать вместо класса, содержащего действительную функциональность. Лучше всего данный шаблон показывает себя в сценариях, где нужно рекурсивно обойти структуру бинарного дерева в поиске суммы значений всех узлов. Для этого вы выполняете поиск в глубину и рекурсивно суммируете в каждом узле значения его левого и правого поддерева.
Дерево поиска обычно реализуется так, что каждый узел в нем имеет левого и правого потомка, которые являются либо также узлами, либо концевыми вершинами. Если такое представление дерева использует для концевых узлов null, то вам придется явно выполнять проверки на нулевых потомков, чтобы останавливать рекурсию в концевом узле, предотвращая попытку получения его значения. Вместо этого вам следует определить интерфейс Node с простым методом getValue() и реализовать его в представляющем узел классе, который вычисляет значение, складывая значения getValues() потомков, как показано на рисунке ниже. Реализуйте такой же интерфейс в классе, представляющем узел, и пусть класс концевого узла возвращает при вызове 0. Теперь нам больше не нужно различать код между концевым узлом и обычным. Необходимость явно проверять наличие null отпала вместе с риском получения исключения (NPE).
Тем не менее лично мне сложно найти применение данному шаблону в типичных базах кода производственной среды, где логика зачастую превосходит сложностью простое накопление чисел. Шаблоны существуют для упрощения решений, но при несоответствующем использовании добавляют сложность, одновременно лишаясь всех преимуществ.
Во многих случаях вам придется писать код, который в определенный момент должен будет проверять что-то для обработки ложных значений. Так почему бы просто не использовать проверки на null изначально, избегая определения дополнительных усложняющих код классов? Бывают случаи, когда рассмотренный шаблон работает прекрасно, но на мой взгляд таких случаев в реальных условиях мало, поскольку его можно использовать только для объектов с методами, содержащими пустые значения, или когда вы можете вернуть что-то гармонично вписывающееся в поток окружающего кода.
Думаю, что нет. В случае класса, представляющего явления из реальной жизни, мы можем сделать обоснованное предположение. Но вышеприведенные типы классов не дают нам для этого никакой возможности, и разобраться в таких случаях можно только, читая код. По этой причине лучше избегать возвращения null вместо других типов, так как у разработчиков редко возникают причины ожидать возвращения null. Если вы этого не ждете, то зачем затрачивать усилия на защиту кода от этих значений?
Передача нулевых параметров
Из предыдущего раздела следует, что допустимо использовать нулевые аргументы при вызове методов с моделирующими область типами параметров, имеющими необязательные значения. При этом методы должны обеспечивать безопасное их использование. На практике же нулевые параметры применяются для гораздо большего спектра задач. Когда нам нужно предоставить такой параметр методу, мы должны обеспечить, чтобы все последующие обработки этого параметра были защищены от null, а это может оказаться нелегко. И даже несмотря на это, ваша программа может находиться в состоянии, скрывающем небезопасное поведение, что приведет к раскрытию проблемы только при других условиях. Предоставление нулевых параметров также добавляет риск вызвать ошибки при изменении кода в его следующих за их добавлением частях.
Как же полностью избежать нулевых параметров?
Нередко нам нужно использовать какую-либо функциональность в существующем методе, но текущий контекст вызова несколько иной, и мы либо не можем обеспечить все вызываемые методом значения, либо требуется больше информации, чем допускает его структура. Само собой мы не хотим повторять практически идентичный метод. Переиспользование является одним из столпов легко обслуживаемого кода, и одинаковая функциональность не должна реализовываться в нескольких местах, поскольку это не только усложнит поддержание синхронности кода, но и внесет риск появления ошибок. Поэтому мы изменяем существующий код под наши задачи и используем null для параметров, которые предоставляются не всегда. Некоторые методы по своей структуре могут принимать по меньшей мере несколько нулевых параметров, другие же не могут совсем. Тем не менее может оказаться затруднительным определить, какие параметры могут иметь значение null, и подходит ли оно для представления отсутствующего значения.
В таких языках, как Python, сигнатуры методов могут содержать предустановленные значения параметров, используемые при отсутствии значения аргумента в вызове метода. Тем не менее в Java такое невозможно. Ближайшим аналогом этого будет использовать перегрузку метода, когда в классе одна и та же сигнатура метода определяется несколько раз с разными параметрами. Один метод будет содержать всю функциональность и принимать весь набор параметров, а другие будут просто “декораторами” для вызова этого метода, каждый из которых будет получать свой поднабор параметров. Методы-декораторы определяют, какие значения должны использовать вместо отсутствующих параметров, чтобы вызывающему компоненту не пришлось их предоставлять. Жестко прописывая, какие значения должны предоставляться, когда у вызывающего их не хватает, мы уменьшаем риск появления ошибок и делаем принимаемые значения параметров явными.
В рассмотренном выше решении нулевые значения по-прежнему передаются в методы внутри объекта, но вызывающий и вызываемые методы спроектированы с учетом этого. Любой метод, вызываемый с одним из этих значений, по умолчанию должен корректно обрабатывать null. При этом нужно запретить сторонним вызывающим объектам передавать нулевые значения для параметров, которые не учтены в структуре, поскольку эти значения могут не поддерживаться, и правильная их обработка не гарантируется.
Воспринимайте null правильно
Все больше языков программирования начинают реализовывать определенные возможности с учетом безопасности. Например, в таких языках, как Clojure, F# и Rust переменные по умолчанию неизменяемы. Компилятор допускает изменение значений только для тех из них, которые объявлены со специальным модификатором. Такой способ использования опасных функций вынуждает программистов переопределять поведение по умолчанию, указывая тем самым, что они осознают степень риска и делают это не без весомых оснований. И к null нам стоит относиться аналогичным образом. Нужно придерживать это значение для особых случаев, где оно будет вполне уместно, ограничив при этом его использование в целом, опять же не ценой усложнения кода креативными обходными решениями. При каждом намерении использовать null вместо перемещающегося между методами значения следует учесть оправданность этого. В таком случае вы должны гарантировать, что в итоге оно не окажется в том месте, где может вызвать проблемы, и другие разработчики будут знать, что значение может быть null. Если же этого обеспечить нельзя, то лучше рассмотреть другие варианты.