Является ли null экземпляром чего-либо?
Нет, нет типа, который null
является instanceof
.
RelationalExpression:
RelationalExpression instanceof ReferenceType
Во время выполнения результат оператора instanceof
равен true
, если значение RelationalExpression не равно null
и ссылка может быть приведена к ReferenceType без поднятия ClassCastException
. В противном случае результат будет false
.
Это означает, что для любого типа E
и R
, для любого E o
, где o == null
, o instanceof R
всегда false
.
К какому набору относится «ноль»?
Существует также специальный тип null , тип выражения null
, который не имеет имени. Поскольку тип null не имеет имени, невозможно объявить переменную типа null или привести к типу null . Ссылка null
является единственным возможным значением выражения типа null . Ссылка null
всегда может быть приведена к любому типу ссылки. На практике программист может игнорировать тип null и просто делать вид, что null
- это просто специальный литерал, который может иметь любой ссылочный тип.
Что такое ноль?
Как сказано выше в цитате JLS, на практике вы можете просто притвориться, что это «просто специальный литерал, который может иметь любой ссылочный тип».
В Java null == null
(это не всегда так в других языках). Также обратите внимание, что по контракту оно также имеет это специальное свойство (от java.lang.Object
):
public boolean equals(Object obj)
* * Для тысячи восемьдесят-одна любой не-
null
опорного значения x
, x.equals(null)
должно return false
.
Это также значение по умолчанию (для переменных, у которых они есть) для всех ссылочных типов:
- Каждая переменная класса, переменная экземпляра или компонент массива инициализируется значением по умолчанию при создании:
- Для всех ссылочных типов значением по умолчанию является
null
.
Как это используется, варьируется. Вы можете использовать его, чтобы включить так называемую ленивую инициализацию полей, где поле будет иметь свое начальное значение null
до его фактического использования, где оно будет заменено «реальным» значением (которое может быть дорого вычислять).
Есть и другие варианты использования. Давайте возьмем реальный пример из java.lang.System
:
public static Console console()
Возвращает : системная консоль, если есть, в противном случае null
.
Это очень распространенный шаблон использования: null
используется для обозначения несуществования объекта.
Вот еще один пример использования, на этот раз из java.io.BufferedReader
:
public String readLine() throws IOException
Возвращает : String
, содержащий содержимое строки, не включая символы окончания строки, или null
, если достигнут конец потока.
Итак, readLine()
будет возвращать instanceof String
для каждой строки, пока, наконец, не вернет null
для обозначения конца. Это позволяет обрабатывать каждую строку следующим образом:
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
Можно спроектировать API так, чтобы условие завершения не зависело от readLine()
, возвращающего null
, но можно увидеть, что этот дизайн имеет преимущество, заключающееся в том, чтобы все было кратким. Обратите внимание, что с пустыми строками проблем нет, потому что пустая строка "" != null
.
Давайте рассмотрим другой пример, на этот раз из java.util.Map<K,V>
:
V get(Object key)
Возвращает значение, которому сопоставлен указанный ключ, или null
, если эта карта не содержит сопоставления для ключа.
Если эта карта допускает значения null
, возвращаемое значение null
не обязательно указывает, что карта не содержит сопоставления для ключа; также возможно, что карта явно отображает ключ на null
. Операция containsKey
может использоваться для различения этих двух случаев.
Здесь мы начинаем видеть, как использование null
может усложнить ситуацию. Первое утверждение говорит, что если ключ не сопоставлен, возвращается null
. Второе утверждение говорит, что даже если ключ сопоставлен, null
может также быть возвращенным.
Напротив, java.util.Hashtable
упрощает задачу, не допуская null
ключей и значений; V get(Object key)
, если возвращается null
, однозначно означает, что ключ не сопоставлен.
Вы можете прочитать остальные API и найти, где и как используется null
. Помните, что они не всегда являются примерами лучшей практики примеров.
Вообще говоря, null
используются в качестве специального значения для обозначения:
- Неинициализированное состояние
- Условие расторжения
- Несуществующий объект
- Неизвестное значение
Как это отображается в памяти?
На Яве? Не твоя забота. И лучше всего так держать.
null
хорошая вещь?
Это теперь пограничный субъективный. Некоторые люди говорят, что null
вызывает много ошибок программиста, которых можно было бы избежать. Некоторые говорят, что на языке, который перехватывает NullPointerException
, например, на Java, хорошо использовать его, потому что вы быстро откажетесь от ошибок программиста. Некоторые люди избегают null
, используя Шаблон нулевого объекта и т. Д.
Это огромная тема сама по себе, поэтому ее лучше обсуждать как ответ на другой вопрос.
Я закончу это цитатой самого изобретателя null
, C.A.R Hoare (из быстрой славы):
Я называю это своей ошибкой в миллиард долларов. Это было изобретение ссылки null
в 1965 году. В то время я разрабатывал первую комплексную систему типов для ссылок на объектно-ориентированном языке. (Алгол Ш). Моя цель состояла в том, чтобы гарантировать, что любое использование ссылок должно быть абсолютно безопасным, с проверкой, выполняемой автоматически компилятором. Но я не мог удержаться от соблазна вставить ссылку null
просто потому, что ее было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.
Видео этой презентации идет глубже; это рекомендуемые часы.