Що таке 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
Повертає :
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
використовуються як особливе значення для позначення:
Як вона представлена в пам'яті?
На Яві? Ніхто з ваших проблем. І найкраще так зберігати.
null
гарна річ?Зараз це є прикордонним суб'єктивним. Деякі люди кажуть, що це null
викликає багато помилок програміста, яких можна було уникнути. Деякі кажуть, що мовою, що NullPointerException
нагадує Java, корисно використовувати її, оскільки ви не зможете швидко помилитися в програмістських помилках. Деякі люди уникають null
використання об'єкта Null , тощо.
Це сама по собі величезна тема, тому її краще обговорити як відповідь на інше питання.
Я закінчу це цитатою самого винахідника null
, CAR CAR Hoare (про швидку славу):
Я називаю це моєю помилкою в мільярд доларів. Це був винахід
null
посилання в 1965 році. У той час я розробляв першу комплексну систему для посилань на об'єктно-орієнтованій мові (ALGOL W). Моя мета полягала в тому, щоб будь-яке використання посилань було абсолютно безпечним, а перевірка виконувалась автоматично компілятором. Але я не міг протистояти спокусі поставитиnull
посилання просто тому, що це було так просто здійснити. Це призвело до незліченних помилок, уразливості та збоїв у системі, які, ймовірно, спричинили біль і шкоду в мільярд доларів за останні сорок років.
Відео цієї презентації йде глибше; це рекомендований годинник.
NIL
) в 1960 році, і, ймовірно, і раніше. Але я не думаю, що Хоар справді намагається претендувати на винахід нульових посилань у цій цитаті.
Чи нульовий примірник чогось?
Ні. Тому null instanceof X
повернемось false
до всіх класів X
. (Не обманюйте той факт, що ви можете призначити null
змінну, тип якої є типом об'єкта. Строго кажучи, призначення передбачає неявне перетворення типу; див. Нижче.)
До якого набору належить "null"?
Це єдиний член нульового типу, де нульовий тип визначається наступним чином:
"Існує також спеціальний тип null, тип виразу null, який не має імені. Оскільки тип null не має імені, неможливо оголосити змінну типу null або передати на null тип. Посилання є єдиним можливим значенням виразу нульового типу. Нульове посилання завжди може бути передано на будь-який тип посилань. На практиці програміст може ігнорувати нульовий тип і просто робити вигляд, що нуль - це лише спеціальний літерал, який може бути будь-яким тип довідки. " JLS 4.1
Що таке нуль?
Дивись вище. У деяких контекстах null
використовується для позначення "ніякого об'єкта" або "невідомого" або "недоступного", але ці значення є специфічними для застосування.
Як вона представлена в пам'яті?
Це конкретна реалізація, і ви не зможете побачити представлення null
в чистій програмі Java. (Але null
представлений як нульова адреса / покажчик машини у більшості, якщо не у всіх реалізаціях Java.)
Що таке нуль?
Це нічого.
Чи нульовий примірник чогось?
Ні, як це ніщо. Це не може бути примірником будь-якої речі.
До якого набору належить null?
Немає жодного набору
Як вона представлена в пам'яті?
Якщо деякі орієнтири на нього такі:
Object o=new Object();
У купі пам'яті деякий простір, призначений новоствореному об'єкту. І o вкаже на цей відведений простір у пам'яті.
Тепер o=null;
Це означає, що тепер o не вказуватиме на цей простір пам'яті об'єкта.
Ключове слово null - це буквальне значення, яке представляє нульову посилання, яке не відноситься до жодного об'єкта . null - значення за замовчуванням змінних типу опорного типу.
Також, можливо, подивіться
Нуль у Java (тм)
У C і C ++ "NULL" - це константа, визначена у файлі заголовка, зі значенням на зразок:
0
або:
0L
або:
((void*)0)
залежно від параметрів компілятора та моделі пам'яті. NULL, власне кажучи, не є частиною C / C ++.
У Java (tm) "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. Нульова посилання спочатку не має типу виконання, але може бути передана будь-якому типу. Значення за замовчуванням для еталонного типу - нульове.
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 кожна змінна класу типу непримітивна завжди посилається на об’єкт цього типу або успадковується, а null є нульовим посиланням на об’єкт класу, але не є нульовим вказівником, тому що в Java немає такого поняття "покажчик", а посилання на клас Об'єкти використовуються замість цього, а null в Java пов'язаний з посиланнями на об'єкт класу, тому ви можете також називати його як "nullref" або "nullrefobj", але це довго, тому просто називайте його "null".
У C ++ ви можете використовувати покажчики та значення nullptr для необов'язкових членів / змінних, тобто член / змінна, яка не має значення, а якщо вона не має значення, то вона дорівнює nullptr, тому як null в Java може бути використаний, наприклад.
У Java існує дві основні категорії типів: примітивний та референтний . Змінні, оголошені значеннями зберігання примітивного типу; змінні, оголошені посиланнями на сховища еталонного типу.
String x = null;
У цьому випадку оператор ініціалізації оголошує змінні "x". "X" зберігає посилання на рядок. Тут нульово . Перш за все, null не є дійсним екземпляром об'єкта, тому для нього не виділено пам'яті. Це просто значення, яке вказує на те, що в даний час посилання на об'єкт не посилається на об'єкт.
На мій погляд, цікавий спосіб побачити null в java - це бачити його як щось, що НЕ позначає відсутність інформації, а просто як буквальне значення, яке може бути присвоєне посиланням будь-якого типу. Якщо ви подумаєте про це, якби він позначав відсутність інформації, тоді для a1 == a2 правда не має сенсу (у випадку, якщо їм обом було призначено значення null), оскільки вони справді могли вказувати на будь-який об’єкт (ми просто не знаю, на які об’єкти вони повинні вказувати) ... До речі, null == null повертає true у Java. Якщо java, наприклад, буде як SQL: 1999, тоді null == null повернеться невідомим (булеве значення в SQL: 1999 може приймати три значення: true, false та unknown, але на практиці невідоме реалізується як null в реальних системах) ... http://en.wikipedia.org/wiki/SQL
Коротка та точна відповідь, яка формально відповідає на всі ваші запитання від JLS:
3.10.7. Нульовий літерал
Тип null має одне значення - нульове посилання, представлене нульовим буквальним null, яке формується з символів ASCII.
Нульовий літерал завжди має нульовий тип.
Виділяється лише посилання типу, який присвоюється нулю. Ви не присвоюєте жодне значення (об'єкт) посиланню. Таке розподіл є специфічним для JVM, скільки посилається на те, і в якій області пам'яті воно буде виділено.