Страницы

Поиск по вопросам

понедельник, 1 октября 2018 г.

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

null - это экземпляр чего-то? К какому типу принадлежит null? Что такое null? Как он представлен в памяти?


Ответ

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
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.
Так же можно посмотреть презентацию про ошибку на миллиард долларов

Комментариев нет:

Отправить комментарий