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

что это null?

Is null экземпляр чего-либо?

что значит null принадлежит?

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

14 ответов


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

нет, типа null это instanceof.

15.20.2 Тип Оператора Сравнения 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 виды типов и значений

существует также специальный null type, тип выражения null, который не имеет имени. Потому что null тип не имеет имени, невозможно объявить переменную типа null введите или бросить в null тип. The null ссылка является единственным возможным значением выражения null тип. The 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. The containsKey операция может использоваться для различения этих двух случаев.

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

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

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

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

  • государственный неинициализированные
  • условие прекращения
  • несуществующий объект
  • неизвестное значение

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

В Java? Не твое дело. И так будет лучше.


Is null хорошая вещь?

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

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

я закончу это цитатой из изобретателя , К. А. Р. Хоар (of слава quicksort):

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

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


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

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

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

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

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

что такое null?

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

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

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


что такое null?

это ничего.

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

нет, поскольку это ничто, это не может быть экземпляром какой-либо вещи.

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

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

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

Если некоторые ориентиры к нему, как:

Object o=new Object();

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

теперь o=null;

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


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


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

также возможно посмотреть

null: Java Glossary


Null в Java (tm)

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

    0

или:

    0L

или:

    ((void*)0)

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

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


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

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


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

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

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

Глава 6 "Набор Инструкций Виртуальной Машины Java" затем упоминает последствия null на других инструкции: он бросает!--9--> для многих из них.

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

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


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

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

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

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

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

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


интересный способ увидеть null в java, на мой взгляд, заключается в том, чтобы увидеть его как нечто, что не обозначает отсутствие информации, а просто как литеральное значение, которое может быть назначено ссылке любого типа. Если вы думаете об этом, если это означало отсутствие информации, то для A1==A2 быть истинным не имеет смысла (в случае, если им обоим было присвоено значение null), поскольку они действительно могли бы указывать на любой объект (мы просто не знаем, на какие объекты они должны указывать)... По путь null == null возвращает true в java. Если java, например, будет как SQL:1999,то null==null вернет unknown (логическое значение в SQL : 1999 может принимать три значения: true, false и unknown, но на практике unknown реализуется как null в реальных системах)... http://en.wikipedia.org/wiki/SQL


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

String x = null;

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


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

3.10.7. Нулевой Литерал

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

литерал null всегда имеет тип null.

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