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

Что такое null?

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

В чем набор null принадлежит?

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

Ответы

Ответ 1

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

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

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

RelationalExpression:
    RelationalExpression instanceof ReferenceType

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

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


Что устанавливает 'null' в?

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 Начальные значения переменных

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

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

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

public static Console console()

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

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

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

public String readLine() throws IOException

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

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

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

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

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

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 object pattern и т.д.

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

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

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

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

Ответ 2

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

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

Что устанавливает 'null' в?

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

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

Что такое null?

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

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

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

Ответ 3

Что такое null?

Это ничего.

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

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

Какой набор имеет значение null?

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

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

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

Object o=new Object();

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

Теперь o=null;

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

Ответ 4

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

Ответ 5

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

Также, возможно, посмотрите

null: Java Glossary

Ответ 6

Null в Java (tm)

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

    0

или

    0L

или

    ((void*)0)

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

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

Ответ 7

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

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

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);

Ответ 8

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

Ответ 9

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

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

Ответ 10

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

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

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

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

2.4. "Типы ссылок и значения" также упоминает null в общих терминах:

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

Ответ 11

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

Ответ 12

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

String x = null;

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

Ответ 13

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

3.10.7. Null Literal

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

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

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

Ответ 14

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

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

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, в отличие от С++, nullptr является undefined, но вместо него используется NULL, который также может использоваться и на С++, но в С++ nullptr более предпочтителен, чем просто NULL, потому что NULL в C всегда связанный с указателями, и что он, поэтому в С++ суффикс "ptr" был добавлен к концу слова, а также все буквы теперь имеют строчные буквы, но это менее важно.

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

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