Что такое null в Java?

Что такое null ?

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

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

Как он представлен в памяти?

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

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

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

 RelationalExpression: RelationalExpression instanceof ReferenceType 

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

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


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

JLS 4.1 Виды типов и ценностей

Существует также специальный тип 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 Начальные значения переменных

  • Каждая переменная classа, переменная экземпляра или компонент массива инициализируется значением по умолчанию при его создании:
    • Для всех типов ссылок значение по умолчанию равно null .

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

Существуют и другие виды использования. Возьмем настоящий пример из java.lang.System :

public static Console console()

Возвраты : системная консоль, если она есть, в противном случае – нет.

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

Вот еще один пример использования, на этот раз из java.io.BufferedReader :

public String readLine() throws IOException

Возвраты : String содержащая содержимое строки, не включая символы окончания строки, или значение null если конец streamа достигнут.

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

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

Можно разработать API так, чтобы условие завершения не зависело от readLine() возвращающего null , но можно видеть, что этот проект имеет преимущество в том, чтобы сделать вещи краткими. Обратите внимание, что нет проблем с пустыми строками, потому что пустая строка "" != null .

Возьмем еще один пример, на этот раз из java.util.Map :

V get(Object key)

Возвращает значение, для которого указан указанный ключ, или null если эта карта не содержит сопоставления для ключа.

Если эта карта допускает null значения, то возвращаемое значение null необязательно указывает, что карта не содержит отображения для ключа; также возможно, что карта явно отображает ключ в значение null . Операция containsKey может использоваться для различения этих двух случаев.

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

Напротив, java.util.Hashtable упрощает работу, не разрешая null ключи и значения; его V get(Object key) , если возвращает null , недвусмысленно означает, что ключ не отображается.

Вы можете прочитать остальные API-интерфейсы и найти, где и как используется значение null . Имейте в виду, что они не всегда являются примерами лучшей практики .

Вообще говоря, null используется как специальное значение для обозначения:

  • Неинициализированное состояние
  • Состояние окончания
  • Несуществующий объект
  • Неизвестное значение

Как он представлен в памяти?

В Java? Ничего из вас. И это лучше всего поддерживать.


Является null ?

Это сейчас пограничная субъективность. Некоторые люди говорят, что null приводит к ошибкам многих программистов, которых можно было избежать. Некоторые говорят, что на языке, который ловит NullPointerException например Java, хорошо использовать его, потому что вы ошибетесь при ошибках программиста. Некоторые люди избегают null , используя шаблон объекта Null и т. Д.

Это огромная тема сама по себе, поэтому ее лучше всего обсудить как ответ на другой вопрос.

Я закончу это цитатой самого изобретателя null , CAR Hoare (из быстрой сортировки):

Я называю это своей ошибкой в ​​миллиард долларов. Это было изобретение null ссылки в 1965 году. В то время я разрабатывал первую всеобъемлющую систему типов для ссылок на объектно-ориентированном языке (ALGOL W). Моя цель состояла в том, чтобы гарантировать, что все использование ссылок должно быть абсолютно безопасным, причем проверка выполняется автоматически компилятором. Но я не мог удержаться от соблазна положить null ссылку, просто потому, что ее было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, вызвали миллиард долларов боли и ущерба за последние сорок лет.

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

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

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

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

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

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

Что такое null?

См. Выше. В некоторых контекстах null используется для обозначения «no object» или «unknown» или «unavailable», но эти значения являются специфичными для приложения.

Как он представлен в памяти?

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

Что такое null?

Ничего.

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

Нет, как ничто. Это не может быть примером какой-либо вещи.

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

Нет никакого набора

Как он представлен в памяти?

Если некоторые ориентиры указывают на это как:

 Object o=new Object(); 

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

Теперь o=null;

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

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

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

Также, возможно, взгляните на

null: Java Glossary

Null в Java ™

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

  0 

или:

  0L 

или:

  ((void*)0) 

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

В Java ™ «null» не является ключевым словом, а является специальным литералом нулевого типа. Его можно использовать для любого ссылочного типа, но не для любого примитивного типа, такого как int или boolean. Нулевой литерал необязательно имеет значение 0. И невозможно применить к типу null или объявить переменную этого типа.

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

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

  // this is false boolean nope = (null instanceof String); // but you can still use it as a String String x = null; "abc".startsWith(null); 

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

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

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

  • aconst_null : например, для установки переменной в значение null как в Object o = null;
  • ifnull и ifnonnull : например, для сравнения объекта с null как в if (o == null)

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

2,4. «Reference Types and Values» также упоминает null в общих терминах:

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

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

 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); } } 

null в Java аналогичен / аналогичен nullptr в C ++.

Программа на C ++:

 class Point { private: int x; int y; public: Point(int ix, int iy) { x = ix; y = iy; } void print() { std::cout << '(' << x << ',' << y << ')'; } }; int main() { Point* p = new Point(3,5); if (p != nullptr) { p->print(); p = nullptr; } else { std::cout << "p is null" << std::endl; } return 0; } 

Такая же программа в Java:

 public class Point { private int x; private int y; public Point(int ix, int iy) { x = ix; y = iy; } public void print() { System.out.print("(" + x + "," + y + ")"); } } class Program { public static void main(String[] args) { Point p = new Point(3,5); if (p != null) { p.print(); p = null; } else { System.out.println("p is null"); } } } 

Теперь вы понимаете из кодов выше, что является нулевым в Java? Если нет, то я рекомендую вам изучить указатели на C / C ++, а затем вы поймете.

Обратите внимание, что в C, в отличие от C ++, значение nullptr не определено, но вместо него используется NULL, который также может использоваться и на C ++, но в C ++ nullptr более предпочтителен, чем просто NULL, поскольку NULL в C всегда связан с указателями, и это это, поэтому в C ++ суффикс «ptr» был добавлен к концу слова, а также все буквы теперь строчные, но это менее важно.

В Java каждая переменная типа non-primitive всегда ссылается на объект этого типа или унаследована, а null - это ссылка на объект null, но не на нулевой указатель, потому что в Java нет такой вещи «указатель», но ссылки на class вместо этого используются объекты, а null в Java относится к объектным ссылкам classа, поэтому вы также можете назвать его как «nullref» или «nullrefobj», но это длинный, так что просто назовите его «null».

В C ++ вы можете использовать указатели и значение nullptr для необязательных членов / переменных, то есть член / переменная, которая не имеет значения, и если она не имеет значения, то она равна nullptr, поэтому, например, как использовать значение null в Java.

Интересный способ увидеть null в java, на мой взгляд, – это увидеть что-то, что НЕ означает отсутствие информации, а просто как буквальное значение, которое может быть присвоено ссылке любого типа. Если вы думаете об этом, если обозначить отсутствие информации, то для a1 == a2 быть истинным не имеет смысла (в случае, если им было присвоено значение null), поскольку они действительно могли бы указывать на ЛЮБОЙ объект (мы просто не знаю, на какие объекты они должны указывать) … Кстати null == null возвращает true в java. Если java, например, будет похож на SQL: 1999, то null == null вернет неизвестный (логическое значение в SQL: 1999 может принимать три значения: true, false и unknown, но на практике неизвестно, что в реальных системах реализовано как null) … http://en.wikipedia.org/wiki/SQL

В Java есть две основные категории типов: примитивная и справочная . Переменные, объявленные значения хранилища примитивного типа; переменные, объявленные ссылками хранилища ссылочного типа.

 String x = null; 

В этом случае оператор инициализации объявляет переменные «x». «X» хранит ссылку на String. Здесь нет значения . Прежде всего, null не является допустимым экземпляром объекта, поэтому для него не выделяется память. Это просто значение, указывающее, что ссылка на объект в настоящее время не ссылается на объект.

Короткий и точный ответ, который отвечает на все ваши вопросы формально из JLS:

3.10.7. Null Literal

Тип null имеет одно значение, нулевую ссылку, представленную нулевым литералом null, который формируется из символов ASCII.

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

Выделяется только ссылка типа, которая присваивается null. Вы не присваиваете ссылку на значение (объект). Такое распределение специфично для JVM, сколько ссылок потребуется и в какой области памяти будет выделено.

  • В чем разница между абстрактным деревом синтаксиса и деревом синтаксиса бетона?
  • Что такое lambda?
  • Как называется дефис-разделенный случай?
  • Аргументы или параметры?
  • Не является ли доступ к члену «закрытый пакет» синонимом доступа по умолчанию (без модификатора)?
  • В чем разница между пространством ядра и пользовательским пространством?
  • В чем разница между методом и функцией?
  • Различия между инициализацией, определением, объявлением переменной
  • Что такое объект без состояния в Java?
  • Разница между DTO, VO, POJO, JavaBeans?
  • Выполнение системного вызова, возвращающего вывод stdout в виде строки
  • Давайте будем гением компьютера.