Что такое 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
это просто специальный литерал, который может иметь любой ссылочный тип.
Что такое ноль?
Как сказано в приведенной выше цитате JLS, на практике вы можете просто притвориться, что это «просто специальный литерал, который может иметь любой ссылочный тип».
В Java null == null
(это не всегда так в других языках). Также обратите внимание, что по контракту оно также имеет это специальное свойство (from 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
для каждой строки, пока он, наконец, не вернет a, 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
используются как специальные значения для обозначения:
Как это представлено в памяти?
На яве? Не твоя забота. И лучше всего так держать.
null
хорошая вещь?Это сейчас пограничный субъективный. Некоторые люди говорят, что это null
вызывает много ошибок программиста, которых можно было бы избежать. Некоторые говорят, что на языке, который ловит NullPointerException
как Java, хорошо использовать его, потому что вы будете быстро отказывать в ошибках программиста. Некоторые люди избегают null
использования шаблона объекта Null и т. Д.
Это огромная тема сама по себе, поэтому ее лучше обсуждать как ответ на другой вопрос.
Я закончу это цитатой из изобретателя самого null
себя, CAR Hoare (быстрой славы):
Я называю это моей ошибкой в миллиард долларов. Это было изобретение
null
ссылки в 1965 году. В то время я разрабатывал первую комплексную систему типов для ссылок на объектно-ориентированном языке (ALGOL W). Моя цель состояла в том, чтобы гарантировать, что любое использование ссылок должно быть абсолютно безопасным, с проверкой, выполняемой автоматически компилятором. Но я не мог удержаться от соблазна вставитьnull
ссылку просто потому, что это было легко реализовать. Это привело к бесчисленным ошибкам, уязвимостям и сбоям системы, которые, вероятно, причинили миллиард долларов боли и ущерба за последние сорок лет.
Видео этой презентации идет глубже; это рекомендуемые часы.
NIL
) в 1960 году, а возможно и раньше. Но я не думаю, что Хоар действительно пытается претендовать на изобретение пустых ссылок в этой цитате.
Является ли null экземпляром чего-либо?
Нет. Поэтому null instanceof X
вернусь false
на все занятия X
. (Не обманывайте себя тем фактом, что вы можете присваивать null
переменную, тип которой является типом объекта. Строго говоря, присваивание включает в себя неявное преобразование типа; см. Ниже.)
К какому набору принадлежит «ноль»?
Это единственный элемент нулевого типа, где нулевой тип определяется следующим образом:
"Существует также специальный нулевой тип, тип выражения null, у которого нет имени. Поскольку нулевой тип не имеет имени, невозможно объявить переменную нулевого типа или привести к нулевому типу. ссылка - это единственно возможное значение выражения нулевого типа. Нулевая ссылка всегда может быть приведена к любому ссылочному типу. На практике программист может игнорировать нулевой тип и просто делать вид, что ноль - это просто специальный литерал, который может иметь любой ссылочный тип. " JLS 4.1
Что такое ноль?
Смотри выше. В некоторых контекстах null
используется для обозначения «нет объекта», «неизвестен» или «недоступен», но эти значения зависят от конкретного приложения.
Как это представлено в памяти?
Это зависит от реализации, и вы не сможете увидеть представление null
в чистой Java-программе. (Но null
представлен как нулевой машинный адрес / указатель в большинстве, если не во всех реализациях Java.)
Что такое ноль?
Это ничего.
Является ли null экземпляром чего-либо?
Нет, поскольку это ничто. Это не может быть примером чего-либо.
К какому набору принадлежит нуль?
Нет любого набора
Как это представлено в памяти?
Если некоторые ссылки указывают на это, как:
Object o=new Object();
В куче памяти выделено место для нового созданного объекта. И о будет указывать на это назначенное место в памяти.
Сейчас o=null;
Это означает, что теперь o не будет указывать на это пространство памяти объекта.
Ключевое слово null - это литерал, представляющий нулевую ссылку, который не относится ни к какому объекту . null - это значение по умолчанию для переменных ссылочного типа.
Также возможно взглянуть на
Нуль в Java (тм)
В C и C ++ «NULL» - это константа, определенная в заголовочном файле, со значением, например:
0
или:
0L
или:
((void*)0)
в зависимости от параметров компилятора и модели памяти. Строго говоря, NULL не является частью самого C / C ++.
В Java (tm) «null» - это не ключевое слово, а специальный литерал типа null. Он может быть приведен к любому ссылочному типу, но не к любому примитивному типу, такому как int или boolean. Нулевой литерал не обязательно имеет значение ноль. И невозможно привести к нулевому типу или объявить переменную этого типа.
Представление байт-кода
Java null
имеет прямую поддержку JVM: для ее реализации используются три инструкции:
aconst_null
: например, чтобы установить переменную null
как вObject o = null;
ifnull
и ifnonnull
: например, чтобы сравнить объект null
как вif (o == null)
Затем в главе 6 «Набор инструкций виртуальной машины Java» упоминается влияние null
других инструкций: NullPointerException
для многих из них они выдаются.
2,4. «Типы ссылок и значения» также упоминаются 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
это не экземпляр String
.
void f(String o)
, это будет иметь больше смысла.
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, но не указателем null, потому что в Java нет такой вещи как «указатель», а ссылки на класс вместо этого используются объекты, и нуль в Java связан со ссылками на объекты класса, поэтому вы также можете называть его как «nullref» или «nullrefobj», но это долго, поэтому просто назовите его «null».
В C ++ вы можете использовать указатели и значение nullptr для необязательных членов / переменных, то есть члена / переменной, которая не имеет значения, а если она не имеет значения, то она равна nullptr, поэтому, например, можно использовать null в Java.
В Java есть две основные категории типов: примитивные и ссылочные . Переменные, объявленные для примитивного типа, хранят значения; переменные, объявленные из ссылочного типа, хранят ссылки.
String x = null;
В этом случае оператор инициализации объявляет переменную «x». «X» хранит ссылку на строку. Здесь ноль . Прежде всего, null не является допустимым экземпляром объекта, поэтому для него не выделена память. Это просто значение, которое указывает, что ссылка на объект в данный момент не ссылается на объект.
На мой взгляд, интересный способ увидеть ноль в Java - это то, что НЕ обозначает отсутствие информации, а просто как буквальное значение, которое может быть присвоено ссылке любого типа. Если вы думаете об этом, если оно обозначает отсутствие информации, то для a1 == a2 быть истинным не имеет смысла (в случае, если им обоим присвоено значение null), поскольку они действительно могут указывать на ЛЮБОЙ объект (мы просто не знаю, на какие объекты они должны указывать) ... кстати, null == null возвращает true в java. Если java, например, будет похож на SQL: 1999, тогда null == null вернет неизвестное (логическое значение в SQL: 1999 может принимать три значения: true, false и unknown, но на практике unknown реализовано как null в реальных системах) ... http://en.wikipedia.org/wiki/SQL
Краткий и точный ответ, который формально отвечает на все ваши вопросы от JLS:
3.10.7. Нулевой литерал
Нулевой тип имеет одно значение, нулевую ссылку, представленную нулевым литералом null, который сформирован из символов ASCII.
Нулевой литерал всегда имеет нулевой тип.
Выделяется только ссылка типа, который назначен на нуль. Вы не присваиваете значение (объект) для ссылки. Такое распределение зависит от JVM, сколько ссылки займет и в какой области памяти оно будет выделено.