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 ):
- Нулевой тип (иначе безымянный) .
null
Буквальным .
- Ссылка нулевое значение. (Обычно сокращенно обозначается как значение 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 действительно особенный».