Що таке null?
Це nullпримірник чого-небудь?
Який набір nullналежить?
Як вона представлена в пам'яті?
Що таке null?
Це nullпримірник чого-небудь?
Який набір nullналежить?
Як вона представлена в пам'яті?
Відповіді:
Чи нульовий примірник чогось?
Ні, немає типу, який nullє instanceof.
instanceofRelationalExpression: 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, скільки посилається на те, і в якій області пам'яті воно буде виділено.