Что такое 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 тип. Thenull
ссылка является единственным возможным значением выражения null тип. Thenull
ссылка всегда может быть приведен к любому ссылочному типу. На практике, программист может игнорировать 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
. ThecontainsKey
операция может использоваться для различения этих двух случаев.
здесь мы начинаем видеть, как с помощью 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;
Это означает, что теперь не будет указывать, что область памяти объекта.
ключевое слово null является литералом, представляющим пустую ссылку, тот, который не относится ни к одному объекту. null-значение по умолчанию для переменных ссылочного типа.
также возможно посмотреть
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, сколько ссылок займет и в какой области памяти оно будет выделено.