что такое null в java
Что такое нуль в Java?
Это null пример чего-либо?
К какому набору null относится?
Как это представлено в памяти?
Является ли null экземпляром чего-либо?
15.20.2 Оператор сравнения типов instanceof
К какому набору принадлежит «ноль»?
JLS 4.1 Виды типов и значений
Как сказано в приведенной выше цитате JLS, на практике вы можете просто притвориться, что это «просто специальный литерал, который может иметь любой ссылочный тип».
В Java null == null (это не всегда так в других языках). Также обратите внимание, что по контракту оно также имеет это специальное свойство (from 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 для каждой строки, пока он, наконец, не вернет a, null чтобы обозначить конец. Это позволяет обрабатывать каждую строку следующим образом:
Давайте возьмем другой пример, на этот раз из java.util.Map :
Возвращает значение, которому сопоставлен указанный ключ, или null если эта карта не содержит сопоставления для ключа.
Здесь мы начинаем видеть, как использование null может усложнить ситуацию. Первое утверждение говорит, что если ключ не сопоставлен, null возвращается. Второе утверждение говорит о том, что даже если ключ сопоставлен, null его также можно вернуть.
Вообще говоря, null используются как специальные значения для обозначения:
Как это представлено в памяти?
На яве? Не твоя забота. И лучше всего так держать.
Это null хорошая вещь?
Это сейчас пограничный субъективный. Некоторые люди говорят, что это null вызывает много ошибок программиста, которых можно было бы избежать. Некоторые говорят, что на языке, который ловит NullPointerException как Java, хорошо использовать его, потому что вы будете быстро отказывать в ошибках программиста. Некоторые люди избегают null использования шаблона объекта Null и т. Д.
Это огромная тема сама по себе, поэтому ее лучше обсуждать как ответ на другой вопрос.
Я закончу это цитатой из изобретателя самого null себя, CAR Hoare (быстрой славы):
Я называю это моей ошибкой в миллиард долларов. Это было изобретение null ссылки в 1965 году. В то время я разрабатывал первую комплексную систему типов для ссылок на объектно-ориентированном языке (ALGOL W). Моя цель состояла в том, чтобы гарантировать, что любое использование ссылок должно быть абсолютно безопасным, с проверкой, выполняемой автоматически компилятором. Но я не мог удержаться от соблазна вставить null ссылку просто потому, что это было легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.
Видео этой презентации идет глубже; это рекомендуемые часы.
Что из себя представляет null?
Свободный перевод вопроса «What is null in Java?» от участника @unj2.
1 ответ 1
В Java null == null (что верно не для всех языков). Из описания java.lang.Object :
public boolean equals(Object obj)
null также является значением по умолчанию для всех ссылочных типов.
Вы можете использовать это свойства для отложенной инициализации, когда поле будет иметь начальное значение null до тех пор, пока оно фактически не будет использовано, где будет заменено «реальным» значением (вычисление которого может быть дорогостоящим).
Есть и другие применения. Если посмотреть на java.lang.System :
Returns: The system console, if any, otherwise null.
Это очень распространённая практика: null используется для обозначения несуществующего объекта.
public String readLine() throws IOException
Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached.
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
К примеру, java.util.Hashtable делает вещи проще путём запрета null в ключах и значениях; так что, если V get(Object key) вернёт null это однозначно говорит о том, что под таким ключом ничего нет.
Операции автоматического анбоксинга на null выбросят java.lang.NullPointerException :
Если резюмировать, то null используется как специальное значение для обозначения:
Как null представлен в памяти?
Небольшое дополнение
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
Что такое нуль в Java?
Является ли null экземпляром чего-либо?
Как это представлено в памяти?
Является ли null экземпляром чего-либо?
Нет, не существует типа, который null является instanceof name__.
15.20.2 Оператор сравнения типов instanceof name __
Во время выполнения результатом оператора instanceof будет true name__, если значение RelationalExpression не равно null и ссылка может быть приведена к ReferenceType без поднятия ClassCastException name__. В противном случае результат будет false name__.
К какому набору принадлежит «ноль»?
JLS 4.1 Виды типов и значений
Как сказано в приведенной выше цитате JLS, на практике вы можете просто притвориться, что это «просто специальный литерал, который может иметь любой ссылочный тип».
В Java null == null (это не всегда так на других языках). Также обратите внимание, что по контракту оно также имеет это специальное свойство (из Java.lang.Object ):
public boolean equals(Object obj)
Это также значение по умолчанию (для переменных, у которых они есть) для всех ссылочных типов:
JLS 4.12.5 Начальные значения переменных
Как это используется, варьируется. Вы можете использовать его для включения так называемой отложенной инициализации полей, где поле будет иметь свое начальное значение null до его фактического использования, где оно будет заменено «реальным» значением (который может быть дорогим для вычисления).
Есть и другие варианты использования. Давайте возьмем реальный пример из Java.lang.System :
Возвращает : системная консоль, если есть, в противном случае null name__.
Это очень распространенный шаблон использования: null используется для обозначения несуществования объекта.
Вот еще один пример использования, на этот раз из Java.io.BufferedReader :
public String readLine() throws IOException
Возвращает : String name__, содержащий содержимое строки, не включая символы завершения строки, или null name__, если достигнут конец потока.
Итак, здесь readLine() будет возвращать instanceof String для каждой строки, пока, наконец, не вернет null для обозначения конца. Это позволяет обрабатывать каждую строку следующим образом:
Давайте возьмем другой пример, на этот раз из Java.util.Map :
Возвращает значение, которому сопоставлен указанный ключ, или null name__, если эта карта не содержит сопоставления для ключа.
Если эта карта допускает значения null name__, то возвращаемое значение null не обязательно указывает, что карта не содержит сопоставления для ключа; также возможно, что карта явно отображает ключ на null name__. Операция containsKey может использоваться для различения этих двух случаев.
Здесь мы начинаем видеть, как использование null может усложнить ситуацию. Первое утверждение говорит, что если ключ не сопоставлен, возвращается null name__. Второе утверждение говорит, что даже если ключ сопоставлен, null можно также вернуть.
Вообще говоря, null используются в качестве специального значения для обозначения:
Как это представлено в памяти?
На яве? Не твоя забота. И лучше всего так держать.
Это сейчас пограничный субъективный. Некоторые люди говорят, что null вызывает много ошибок программиста, которых можно было бы избежать. Некоторые говорят, что на языке, который перехватывает NullPointerException name__, например, Java, его хорошо использовать, потому что вы быстро справитесь с ошибками программиста. Некоторые люди избегают null name__, используя шаблон нулевого объекта и т.д.
Это огромная тема сама по себе, поэтому ее лучше обсуждать как ответ на другой вопрос.
Я закончу это цитатой самого изобретателя null name__, C.A.R Hoare (о славе быстрой сортировки):
Я называю это своей ошибкой в миллиард долларов. Это было изобретение ссылки null в 1965 году. В то время я разрабатывал первую комплексную систему типов для ссылок на объектно-ориентированном языке (ALGOL W). Моя цель состояла в том, чтобы гарантировать, что любое использование ссылок должно быть абсолютно безопасным, с проверкой, выполняемой автоматически компилятором. Но я не мог удержаться от соблазна вставить ссылку null просто потому, что это было легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.
видео этой презентации идет глубже; это рекомендуемые часы.
Что такое 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
Для начала надо понять, как к null пришло человечество.
Во время написания кода в объектно-ориентированной парадигме вы представляете свою программу в виде совокупности и взаимодействия объектов, каждый из которых является экземпляром определённого класса.
И всё бы ничего, но что делать, если вам необходимо обозначить отсутствие объекта? Например, отсутствие пользователя, какого-то ресурса и т.д.
Т.е значения этого поля на данный момент нет, но в дальнейшем вполне возможно, что оно появится: например, пользователь его добавит в личном кабинете, или укажет в отделени банка сотруднику.
Казалось бы, всё и на этом тему можно закрывать, ведь все довольны и счастливы! Не совсем.
«There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.» JLS 4.1
В итоге null стал жертвой того, что, благодаря возможности присвоить любому ссылочному значению или вернуть из метода, его стали использовать неправильно. И возненавидели.
Но, как и в ситуации с ножом, у null тоже есть правила безопасности и о них мы и поговорим.
Не доверяй и проверяй
Самая явная и очевидная проверка на null в Java выглядит следующим образом:
Несмотря на все наши усилия и договорённости, null может также просочиться в объект ещё на этапе его создания.
Т.е. перед инициализацией проверить допустимость значений, которые получены конструктором.
К счастью, для этого в уже знакомом java.util.Objects есть необходимые методы:
Благодаря чему, наш Person приобретает дополнительные проверки и вы всегда быстро поймёте какое поле было проинициализировано неправильно:
Вопрос:
Ответ:
Да, есть и их также можно использовать для валидации значений:
Однако, я ими пользоваться не рекомендую и вот почему:
Аккуратность в проверках
Помните, что вызов метода на null неизбежно породит java.lang.NullPointerException :
Примитивы не так уж и примитивны
Как вы думаете, что будет при выполнении следующего кода:
Аккуратнее со строками
Например, как это сделано в java.util.Objects :
В случае написания функциональности, где не все параметры всегда предоставляются, обычно велик соблазн написать один метод и далее использовать его, передавая при необходимости null в параметры, которые могут отсутствовать.
Например, обновление статуса с дополнительной информацией (по возможности):
При этом, details вполне может отсутствовать и зачастую использование сводится к:
В таком случае, лучше перегрузить метод и сделать:
Старайтесь минимизировать явную передачу null в методы.
Во-первых, null в методе делает его менее читабельным, особенно, если null значений несколько, например:
Отсутствие значения не всегда null
Одной из самых популярных ошибок в использовании null является возвращение его там, где ожидается коллекция данных.
Разберём пример: вы написали телефонную книгу, где есть возможность получить список номеров по имени абонента:
Казалось бы, всё правильно, но нет!
Точно также, если вы разрабатываете функционал, где одним из параметров является необязательная коллекция данных: не делайте возможность передачи вместо неё null :
Если tags необязательное значение для поиска, то при отсутствии значения передавайте пустое множество:
Либо сделайте два метода: с tags в сигнатуре и без.
findByNameAndTags(final String name) < // some code >«>
Например, вам необходимо множество кодов ошибок в валидаторе значений:
Как вариант можно возвращать ещё итератор.
Для примера, пусть необходим метод, который в телефонной книге ищет пользователя по имени и фамилии (как уникальным идентификаторам пользователя в нашей реализации):
Очевидно, что может возникнуть ситуация, когда будет произведен поиск несуществующего пользователя (например, не зарегестрированного у нас).
Что делать в таком случае?
Варианта, на самом деле, три:
В таком случае, использование может быть в виде:
Есть три способа создать Optional :
Никогда не смешивайте null и Optional :
Это путь в ад и к ненависти.
Доверяйте, но с аннотациями
К сожалению, в Java нет какого-то общего стандарта, и существует несколько видов аннотаций для этого, например:
В целом, я уверен, существуют еще несколько, но я выделил наиболее популярные (исключая Android специфичные) на данный момент.
Какую выбрать и как использовать?
На самом деле, вопрос сложный, но я в своих проектах пользуюсь тем, что предоставляет JSR-305, т.е javax.annotation.Nonnull и т.д.
Благодаря плагину и аннотациям из JSR-305 получается разметить и сгенерировать код с билдерами и проверками на null :
Но не возвращаемые значения! Возвращаемые значения надо размечать вручную самому и явно.
Это довольно удобно и практично.
Грубо говоря, это как разметка на дороге, вы понимаете, где может быть опасное место, а где в целом безопасный отрезок трассы, но это не защитит вас от грузовика по встречной полосе, если кто-то на нём вырулит:
Не задействуйте null для указания ошибок — лучше выбрасывайте явное исключение.
Отдельную благодарность за ревью и помощь автор хочет выразить следующим людям из твиттера: