Является ли null объектом?

119

Является ли null Objectв Java?

зарегистрированный пользователь
источник
41
Нет, это не так, и для тех, кто задается вопросом, почему такой вопрос, существуют языки, в которых null действительно является таким же объектом, как любой, например Ruby.
JRL,
7
В Scala, который очень тщательно относится к типам, есть тип Null(на самом деле черта ), имеющий единственный экземпляр null.
Carl Smotricz,
1
@JRL: Просто из любопытства, мне интересно, как это влияет на то, как работает JRuby ... (я недостаточно знаком с этим уровнем реализации, чтобы знать наверняка.)
Бенджамин Оукс
Чтобы добавить к комментарию @ JRL - приблизительный эквивалент Ruby для nullis nil, который является экземпляром NilClass
Элиот Сайкс
Или javascript, в котором null instanceof Objectfalse, но typeof(null)возвращается 'object'. В таком случае это объект? Кто знает.
Дон Хэтч

Ответы:

166

Если бы null был объектом, он поддерживал бы такие методы java.lang.Object, как equals(). Однако это не так - любой вызов метода с нулевым значением приводит к созданию файла NullPointerException.

И вот что говорится в спецификации языка Java по этой теме:

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

Я думаю, это можно свести к «нулю особенный».

Майкл Боргвардт
источник
1
Таким образом, объект в Java является объектом, только если он равен или подклассам java.lang.Object. Практически - да. Вы не можете создать класс, который не является подклассом java.lang.Object, но я никогда не думал об этом с более философской точки зрения
Андреас Дольк
Любопытно, что в документации APINullPointerException упоминается » nullобъект«… :) Но тогда можно было говорить и о «нулевых указателях»…
Люми
Вы сказали: «Пустую ссылку всегда можно привести к любому ссылочному типу». Итак, можем ли мы вернуть null (типизированный - если разрешено) в методе с типом ссылки на объект (возвращаемого)?
Srichakradhar
1
@Srichakradhar: да, мы можем! Что легче узнать, попробовав это в коде, чем задавая здесь вопросы.
Майкл Боргвардт,
1
«Пустая ссылка - единственное возможное значение выражения нулевого типа». Пришло время прочитать документ со спецификациями. :)
sofs1
32

Согласно спецификации Java , nullэто тип, который может быть назначен объектной переменной (как значение, как указано в комментарии). Однако вы не можете создавать или создавать переменные этого типа, вы должны использовать литерал, nullпредоставленный компилятором.

Дана Разумная
источник
8
null - это тип и значение.
Иоахим Зауэр,
5
nullНазвание является «экземпляром» из nullтипа, по- видимому.
Strager
nullне переменная, это литерал: JLS, 3.10.7. The Null Literal
Джеральд Брозер
Re « nullэто тип, который может быть назначен »: 1) null(в коде) - это нулевой литерал , а не нулевой тип 2) Типы не могут быть присвоены переменным в Java в целом, см. JLS 4.1: « Есть [... ] два типа значений данных, которые могут храниться в переменных [...]: примитивные значения (§4.2) и ссылочные значения (§4.3). « Это пустая ссылка, которая может быть назначена через nullлитерал. ... продолжение ...
Джеральд Брозер
3) объект в « объектной переменной », по сравнению с переменной класса, обычно ссылается не на тип, а на время жизни. При обращении к типу это обычно называется переменной ссылочного типа или, для краткости, ссылочной (типовой) переменной. Мне известны 4 типа в API Java, которые предоставляют переменные экземпляра / объекта (их может быть больше): массивы с егоlength и подклассами java.awt.geom.Point2D.
Герольд Брозер
28

Абсолютно нет: null instanceof Objectвозвращает false.

Дарин Димитров
источник
17
И все же это присваивание совместимо со всеми ссылочными типами.
Крис Вест,
12

Нет, это не объект.

Эрих Кицмюллер
источник
12

Нуль - это отсутствие объекта.

Томми Карлье
источник
Но нулевой тип присваивается каждому ссылочному типу.
Том Хотин - tackline
Не существует «нулевого типа»; null - это конкретное значение непримитивных выражений (то есть ссылок; в Java, насколько я понимаю, тоже нет "ссылочного типа").
Томми МакГуайр,
3
Томми: JLS 4.1: «Существует также специальный нулевой тип, тип выражения null, у которого нет имени».
Кен
12

JRL написал:

Нет, это не так, ...

Как часто бывает, это зависит от того, с чего вы на это смотрите, кому вы больше верите.

Согласно JLS, да, это так . Особенно, если перефразировать вопрос: «Является ли nullбуквальным типом Object?». В дополнение к JLS 4.1, процитированному Майклом Боргвардтом выше:

См. JLS 3.10.7 :

Нулевой литерал всегда имеет нулевой тип.

и JLS 4.10 :

Подтипами типа T являются все типы U, такие что T является супертипом U и нулевым типом.

или JLS 4.10.2 :

Все прямые супертипы нулевого типа являются ссылочными типами, кроме самого нулевого типа.

[Подчеркнуто мной.]

Согласно компилятору Eclipse 2019-09, это не так :

true.toString();  // Cannot invoke toString() on the primitive type boolean
null.toString();  // Cannot invoke toString() on the primitive type null

Согласно OpenJDK 12.0.1 javac это :

true.toString();  // error: boolean cannot be dereferenced
null.toString();  // error: <null> cannot be dereferenced

Если угловые скобки подразумевают, что nullэто не примитивный тип. И согласно JLS 4.1 :

В языке программирования Java есть два типа типов: примитивные типы (...) и ссылочные типы (...).

если не одно, то другое.


Клауди писал:

null - это некрасиво.

Наоборот, nullкрасиво. Что бы вы предложили в качестве значения по умолчанию для переменной ссылочного типа? Произвольная битовая комбинация? Добро пожаловать в нарушение прав доступа или, что еще хуже, в ад указателей!


Иоахим Зауэр писал:

null - это тип и значение.

Фактически, есть три элемента в сочетании с null (см. Также JLS 3.10.7 ):

  1. Нулевой тип (иначе безымянный) .
  2. null Буквальным .
  3. Ссылка нулевое значение. (Обычно сокращенно обозначается как значение null или просто null .)

(1) Обратите внимание, что согласно JLS 4.10.2, процитированному выше, нулевой тип использует множественное наследование не только для интерфейсов, но и для классов. Все мы знаем, что это невозможно для нас, программистов.

(2) Нулевой литерал можно представить как переменную, определяемую как:

JVM_global final null_type null = new null_type();

Также обратите внимание на JLS 3.9 :

Иногда в качестве ключевых слов ошибочно принимают различные последовательности символов:

  • nullне ключевое слово, а скорее нулевой литерал ( §3.10.7 ).

Что касается null instanceof <any type>

Принимая во внимание JLS 4.10.2 (« нулевой тип - это подтип каждого типа»), null instanceof <any type>должно предполагаться, что он должен оцениваться true, не так ли? На первый взгляд, да, но JLS 15.20.2 дает ясный ответ:

[...] результат от instanceofоператора является , trueесли значение в ВыраженияОтношении неnull [...]. В противном случае результат естьfalse .

[Подчеркнуто мной.]

Спросите себя, что имеет больше смысла (с точки зрения прикладного программиста):

  • Предоставление falseи, таким образом, указание на то, что ссылочное выражение не относится к типу, доступному нам, т.е. указание, что оно не ссылается на что-либо полезное для нас.

  • или давая true, таким образом сообщая нам, что выражение оценивает специальную ссылку, нулевую ссылку , ссылающуюся на «объект», который мы не знаем, существует ли он вообще, и который имеет специальный нулевой тип, который не имеет имени, не подвергается us, но через нулевой литерал , является ли подтип любого типа, включая множественное наследование, и его все равно следует игнорировать? Рассмотрим также более практичный пример:

     class Car implements Vehicle {  
     ...
     Vehicle car = null;
     ...
     boolean b = car instanceof Car;  // True? There's not even an instance
     ...                              // which could be of type Car.

Что также приводит к:

Почему instanceofнельзя сказать что-то об nullОбъективности?

Это называется instanceofнет sameorsubtypeof. Это означает, что мы сравниваем тип экземпляра с типом, а не с двумя типами. Теперь nullозначает: «Нет экземпляра», а если экземпляра нет, нет и его типа. Очевидно, что сравнение ничего с чем-то должно вести false.

Или в "более" реальном примере:

  • У меня в руках полноразмерное изображение яблока ( = эталонного типа ) с надписью «Большое яблоко» ( = название эталонного типа ).
  • Передо мной стол ( = куча ).
  • Если на столе есть яблоко ( = экземпляр ), к нему подключен шнур ( = ссылка ).
  • Другой конец этого шнура я держу в руке ( = контрольная переменная ).
  • Я прорисовываю яблоко вдоль шнура и сравниваю его с моей картинкой ( = instanceof ).
  • Если яблоко такого же размера или больше, чем изображение, к нему применяется надпись «Большое Яблоко» ( = true ).
  • Если меньше, то нет ( = ложь ).
  • Если на столе нет яблока (= нет экземпляра ) и, следовательно, нет шнура ( = null ), запись также не применяется ( = false ). Потому что: Разве не яблоко - большое яблоко? Нет, это не так.


Как резюмирует Майкл: «null действительно особенный».

Джеральд Брозер
источник
2
Apple и null? Не боитесь судебного процесса? :)
Gábor Lipták
9

Нет, это не экземпляр класса или класса. Это ссылка ни на что.

Изменить : не читал спецификацию, поэтому приведенное выше может быть неточным на 100%.

cherouvim
источник
5

Как объяснялось в главе 4.1 Типы типов и значений спецификации языка Java, null - это тип, который имеет одно значение, нулевую ссылку (и представлен литералом null):

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

Вы можете прочитать о шаблоне пустого объекта (который я не рекомендую). См. C2 Wiki или Wikipedia для получения дополнительной информации об этом шаблоне.

Паскаль Тивент
источник
5

Нет. Даже если бы это было так, это бесполезно, так как у него нет никаких методов или полей.

Торбьёрн Равн Андерсен
источник
4

Нет, не является объектом, поскольку null instanceof Object всегда будет возвращать false, также есть только один null, а не по одному для каждого класса.

userj29874319284
источник
3
На самом деле null instanceof <anytype>тоже вернется false.
Bombe
4

Согласно спецификации Java ,

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

Питер Лоури
источник
4

Java обрабатывает объекты через ссылки. Null - это нарушение объектно-ориентированности Java, поскольку оно опускает вас ниже объектно-ориентированного уровня. Нет, это не объект, это ЗНАЧЕНИЕ ссылки. И это не имеет ничего общего с объектными парадигмами, но относится к технологии Java, которая позволяет использовать объекты.

Павел Зайцев
источник
3

Является ли null экземпляром java.lang.Object? Нет .

Является ли null объектом ? зависит от определения « есть ».

irreputable
источник
2
Object foo = null;
System.out.println(foo.toString()); 

Первая строка показывает, что nullее можно присвоить типу Object, но вторая строка продемонстрирует, что это, конечно, не так, Objectи в конечном итоге приведет кjava.lang.NullPointerException

Мэтт Стивенсон
источник