Что такое null
?
Является ли null
экземпляром чего-либо?
В чем набор null
принадлежит?
Как он представлен в памяти?
Что такое null
?
Является ли null
экземпляром чего-либо?
В чем набор null
принадлежит?
Как он представлен в памяти?
Является ли null экземпляром чего-либо?
Нет, нет типа, который null
является instanceof
.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
Во время выполнения результат оператора
instanceof
равенtrue
, если значение RelationalExpression не равноnull
, и ссылка может быть перенесена в ReferenceType без повышения aClassCastException
. В противном случае результатfalse
.
Это означает, что для любого типа E
и R
для любого E o
, где o == null
, o instanceof R
всегда false
.
Что устанавливает 'null' в?
Существует также специальный тип 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
.
Это также значение по умолчанию (для переменных, которые есть у них) для всех типов ссылок:
- Каждая переменная класса, переменная экземпляра или компонент массива инициализируется значением по умолчанию при его создании:
- Для всех типов ссылок значение по умолчанию
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
просто потому, что ее было так легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, вызвали миллиард долларов боли и ущерба за последние сорок лет.
Видео этой презентации идет глубже; это рекомендуемые часы.
Является ли null экземпляром чего-либо?
Нет. Поэтому null instanceof X
вернет false
для всех классов X
. (Не обманывайтесь тем фактом, что вы можете назначить null
переменной, тип которой является типом объекта. Строго говоря, назначение подразумевает неявное преобразование типа, см. Ниже.)
Что устанавливает '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 всегда будет false.
Ключевое слово null - это литерал, представляющий нулевую ссылку, , которая не относится к какому-либо объекту. null - значение по умолчанию для ссылочных переменных.
Также, возможно, посмотрите
Null в Java (tm)
В C и С++ "NULL" - это константа, определенная в файле заголовка со значением, например:
0
или
0L
или
((void*)0)
в зависимости от параметров модели компилятора и модели памяти. NULL не является, строго говоря, частью самого C/С++.
В Java (tm) "null" не является ключевым словом, а является специальным литералом типа null. Его можно использовать для любого ссылочного типа, но не для любого примитивного типа, такого как int или boolean. Нулевой литерал необязательно имеет значение 0. И невозможно применить к типу 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
.
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
имеет прямую поддержку JVM: для ее реализации используются три команды:
aconst_null
: например. для установки переменной в null
, как в Object o = null;
ifnull
и ifnonnull
: например. для сравнения объекта с null
, как в if (o == null)
Глава 6 "Набор инструкций виртуальной машины Java" затем описывает эффекты null
в других инструкциях: он выдает NullPointerException
для многих из них.
2.4. "Типы ссылок и значения" также упоминает null
в общих терминах:
Базовое значение также может быть специальной нулевой ссылкой, ссылкой на какой-либо объект, который будет обозначаться здесь нулем. Первоначальная нулевая ссылка не имеет типа времени выполнения, но может быть применена к любому типу. Значение по умолчанию для ссылочного типа равно null.
Интересным способом увидеть 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
В Java существуют две основные категории типов: примитивная и ссылка. Переменные, объявленные значения хранилища примитивного типа; переменные, объявленные ссылками хранилища ссылочного типа.
String x = null;
В этом случае оператор инициализации объявляет переменные "x". "x" хранит ссылку на String. Здесь null. Прежде всего, null не является допустимым экземпляром объекта, поэтому для него не выделяется память. Это просто значение, указывающее, что ссылка на объект в настоящее время не ссылается на объект.
Короткий и точный ответ, который формально отвечает на все ваши вопросы из JLS:
3.10.7. Null Literal
Тип null имеет одно значение, нулевую ссылку, представленную null literal null, который формируется из символов ASCII.
Нулевой литерал всегда имеет нулевой тип.
Выделяется только ссылка типа, присвоенного нулевому значению. Вы не присваиваете ссылку на значение (объект). Такое распределение специфично для JVM, сколько ссылок потребуется и в какой области памяти будет выделено.
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 может использоваться.