Что такое нуль в Java? - PullRequest
       38

Что такое нуль в Java?

229 голосов
/ 25 апреля 2010

Что такое null?

Является ли null экземпляром чего-либо?

К какому набору относится null?

Как это отображается в памяти?

Ответы [ 14 ]

296 голосов
/ 25 апреля 2010

Является ли null экземпляром чего-либо?

Нет, нет типа, который null является instanceof.

15.20.2 Оператор сравнения типов instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

Во время выполнения результат оператора instanceof равен true, если значение RelationalExpression не равно null и ссылка может быть приведена к ReferenceType без поднятия ClassCastException. В противном случае результат будет false.

Это означает, что для любого типа E и R, для любого E o, где o == null, o instanceof R всегда false.


К какому набору относится «ноль»?

JLS 4.1 Виды типов и значений

Существует также специальный тип 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.

Это также значение по умолчанию (для переменных, у которых они есть) для всех ссылочных типов:

JLS 4.12.5 Начальные значения переменных

  • Каждая переменная класса, переменная экземпляра или компонент массива инициализируется значением по умолчанию при создании:
    • Для всех ссылочных типов значением по умолчанию является 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 просто потому, что ее было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.

Видео этой презентации идет глубже; это рекомендуемые часы.

29 голосов
/ 25 апреля 2010

Является ли null экземпляром чего-либо?

Нет. Вот почему null instanceof X вернет false для всех классов X. (Не обманывайте себя тем, что вы можете присваивать null переменной, тип которой является типом объекта. Строго говоря, присваивание подразумевает неявное преобразование типа; см. Ниже.)

К какому набору относится «ноль»?

Это единственный член нулевого типа, где нулевой тип определяется следующим образом:

"Существует также специальный нулевой тип, тип выражения null, у которого нет имени. Поскольку нулевой тип не имеет имени, невозможно объявить переменную нулевого типа или привести к нулевой тип. Нулевая ссылка - единственно возможное значение выражения нулевого типа. Нулевая ссылка всегда может быть приведена к любому ссылочному типу. На практике программист может игнорировать нулевой тип и просто делать вид, что ноль - это просто особый литерал, который может иметь любой ссылочный тип. " JLS 4.1

Что такое ноль?

см. Выше. В некоторых контекстах null используется для обозначения «нет объекта», «неизвестен» или «недоступен», но эти значения зависят от конкретного приложения.

Как это отображается в памяти?

Это зависит от реализации, и вы не сможете увидеть представление null в чисто Java-программе. (Но null представляется как нулевой машинный адрес / указатель в большинстве, если не во всех реализациях Java.)

13 голосов
/ 31 августа 2011

Что такое ноль?

Это ничто.

Является ли null экземпляром чего-либо?

Нет, поскольку это ничто. Это не может быть примером чего-либо.

К какому набору принадлежит нуль?

Нет любого набора

Как это отображается в памяти?

Если на него ссылаются, например:

Object o=new Object();

В куче памяти выделено пространство для нового созданного объекта. И o укажет на это назначенное место в памяти.

Сейчас o=null;

Это означает, что теперь o не будет указывать на это пространство памяти объекта.

8 голосов
/ 25 апреля 2010

Нет, это не экземпляр чего-либо, instanceof всегда будет ложным.

6 голосов
/ 25 апреля 2010

Ключевое слово null - это литерал, представляющий нулевую ссылку, , который не относится ни к какому объекту . null - значение по умолчанию для переменных ссылочного типа.

Также, возможно, посмотрите на

null: Глоссарий Java

5 голосов
/ 06 мая 2011

Ноль в Java (тм)

В C и C ++ «NULL» - это константа, определенная в заголовочном файле, со значением вроде:

    0

или

    0L

или

    ((void*)0)

в зависимости от параметров компилятора и модели памяти. Строго говоря, NULL не является частью самого C / C ++.

В Java (tm) "null" - это не ключевое слово, а специальный литерал типа null. Он может быть приведен к любому ссылочному типу, но не к любому примитивному типу, такому как int или boolean. Нулевой литерал не обязательно имеет значение ноль. И невозможно привести к нулевому типу или объявить переменную этого типа.

4 голосов

Представление байт-кода

Java null имеет прямую поддержку JVM: для ее реализации используются три инструкции:

  • aconst_null: например установить переменную на null как в Object o = null;
  • ifnull и ifnonnull: например, сравнить объект с null как в if (o == null)

Глава 6 «Набор инструкций виртуальной машины Java» затем упоминает влияние null на другие инструкции: для многих из них выбрасывается NullPointerException.

2,4. «Типы и значения ссылок» также упоминает null в общих выражениях:

Ссылочным значением также может быть специальная нулевая ссылка, ссылка на отсутствие объекта, которая будет обозначаться здесь нулевой. Нулевая ссылка изначально не имеет типа времени выполнения, но может быть приведена к любому типу. Значением по умолчанию для ссылочного типа является ноль.

4 голосов
/ 25 апреля 2010

Нуль не является экземпляром какого-либо класса.

Однако вы можете присвоить null переменным любого типа (объекта или массива):

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);
3 голосов
/ 25 апреля 2010

null - это особое значение, оно не является экземпляром чего-либо. По понятной причине это не может быть instanceof ничем.

2 голосов
/ 25 апреля 2010

null - это специальное значение, которое не является экземпляром какого-либо класса. Это иллюстрируется следующей программой:

public class X {
   void f(Object o)
   { 
      System.out.println(o instanceof String);   // Output is "false"
   }
   public static void main(String[] args) {
      new X().f(null);
   }
}
...