Что из себя представляет null?

144
14 ноября 2018, 07:20
  1. null - это экземпляр чего-то?
  2. К какому типу принадлежит null?
  3. Что такое null?
  4. Как он представлен в памяти?
Answer 1
null - это экземпляр чего-то?

Нет такого типа, которому бы соответствовал instanceof от null.

15.20.2 Type Comparison Operator instanceof

RelationalExpression:
  RelationalExpression instanceof ReferenceType

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

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

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

JLS 4.1 The Kinds of Types and Values.

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

Что такое null?

Как сказано в цитате из JLS выше, можно считать, что "null - это просто специальный литерал, который может быть любым ссылочным типом".

В Java null == null (что верно не для всех языков). Из описания java.lang.Object:

public boolean equals(Object obj)

Для любой не null переменной x, x.equals(null) должно возвращать false.

null также является значением по умолчанию для всех ссылочных типов.

JLS 4.12.5 Initial Values of Variables:

  • Любой экземпляр класса, переменная или элемент массива специализируются значением по умолчанию:
    • Для всех ссылочных типов (§4.3), дефолтное значение - null.

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

Есть и другие применения. Если посмотреть на java.lang.System:

public static Console console()

Returns: The system console, if any, otherwise null.

Это очень распространённая практика: null используется для обозначения несуществующего объекта.

Другой пример - java.io.BufferedReader:

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.

readLine() будет возвращать instanceof String для каждой строки, пока не получит null, обозначающий конец. Это позволяет обрабатывать каждую строку следующим образом:

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

Примечание: пустая строка - не проблема, т.к. "" != null.

Давайте рассмотри java.util.Map<K,V>:

V get(Object key)

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

If this map permits null values, then a return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.

Здесь мы видим, что использование null может усложнить дело. Тут говорится, что, если такого ключа нет, будет возвращён null. Второе утверждение гласит, что даже если элемент по такому ключу есть, всё равно может вернуться null.

К примеру, java.util.Hashtable делает вещи проще путём запрета null в ключах и значениях; так что, если V get(Object key) вернёт null это однозначно говорит о том, что под таким ключом ничего нет.

Операции автоматического боксинга/анбоксинга на null выбросят java.lang.NullPointerException:

Integer i = null;
// при анбоксинге null в integer будет выброшен NullPointerException 
int a = i;

Если резюмировать, то null используется как специальное значение для обозначения:

  • Не инициализированного состояния.
  • Терминальное условие
  • Несуществующий объект.
  • Неизвестное значение.
Как null представлен в памяти?

Из спецификации JVM:

The Java Virtual Machine specification does not mandate a concrete value encoding null.

Небольшое дополнение

Интересная цитата C.A.R Hoare:

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.

Так же можно посмотреть презентацию про ошибку на миллиард долларов.

READ ALSO
Используя Regex удалить всё, кроме того, что подходит под паттерн

Используя Regex удалить всё, кроме того, что подходит под паттерн

Собственно вопрос в том, как реализовать код который из string будет выбирать только ту часть, что удовлетворяет условиям, а всё остальное удалятьВ...

136
Почему isInterrupted() не меняет свое значение?

Почему isInterrupted() не меняет свое значение?

Решил проверить срабатывание isInterrupted() следующим кодом:

157
freemarker ошибка на странице

freemarker ошибка на странице

Все страницы отображаются нормально, только в одной отображается все кроме текста добавления который подтягивается с базы и отображения...

186
pool соединений(JDBC) с базой данных mySQL из GlassFish 4.1.2

pool соединений(JDBC) с базой данных mySQL из GlassFish 4.1.2

При ping-е соединения выходит ошибка:

156