Явное поведение Java

Я пытаюсь понять, как null работает в Java.

Если мы присваиваем null любому объекту, что происходит на самом деле за сценой? Указывает ли он адрес ячейки памяти, указывающий на объект null "или что-то еще?

Я пробовал следующую программу, и я понял, что все null указывают на то же местоположение.

Но может ли кто-нибудь сказать мне, как Java бросает NullPointerException и как null работает в Java?

class Animal{
}

class Dog{
}


public class testItClass {

    public static void main(String args[]){
        Animal animal=null;
        Dog dog=null;

        if(((Object)dog) == ((Object)animal))
            System.out.println("Equal");
    }

}

Выход

Ровный.

Ответ 1

если мы присваиваем null любому объекту то, что на самом деле является его некоторым местом памяти в куче ИЛИ чем-либо еще.

Следует различать reference и object. Вы можете назначить null ссылке. Объекты обычно создаются в куче, используя оператор new. Он возвращает вам ссылку на объект.

A a = new A();

объект с типом A создается в куче. Вам дается ссылка A. Если теперь вы назначаете

a = null;

сам объект все еще находится в куче, но вы не сможете получить к нему доступ, используя ссылку A.

Обратите внимание, что объект может быть собран позже.

UPD:

Я создал этот класс, чтобы увидеть его байт-код (первый раз для меня):

public class NullTest {
    public static void main (String[] args) {
        Object o = new Object();
        o = null;
        o.notifyAll();
    }
}

И он производит:

C:\Users\Nikolay\workspace\TestNull\bin>javap -c NullTest.class
Compiled from "NullTest.java"
public class NullTest {
  public NullTest();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #3                  // class java/lang/Object
       3: dup
       4: invokespecial #8                  // Method java/lang/Object."<init>":()V
       7: astore_1
       8: aconst_null
       9: astore_1
      10: aload_1
      11: invokevirtual #16                 // Method java/lang/Object.notifyAll:()V
      14: return
}

Вы можете увидеть, что значение null задано для ссылочных результатов:

8: aconst_null
9: astore_1

Список инструкций байтового кода

В основном он ставит значение null в начало стека и затем сохраняет значение ссылки. Но этот механизм и эталонная реализация являются внутренними для JVM.

Как реализована ссылка на объект java?

Ответ 2

Следующее объявляет ссылку на объект класса Animal (или его подкласс) и инициализирует его null:

Animal animal = null;

Здесь сама ссылка занимает некоторое пространство. Поскольку не существует связанного объекта, дополнительных затрат памяти нет.

Если вы попытаетесь использовать ссылку null, обратившись к объекту:

Animal cat = null;
if (cat.equals(dog)) { ... } // throws NPE

вы получите NullPointerException.

Однако, нормально работать с самой ссылкой null, если вы не пытаетесь разыменовать ее:

Animal cat = null;
Animal dog = null
if (cat == dog) { ... }      // works fine

Ответ 3

Null in java создан на основе шаблона NULL Object.

Объект NULL означает несуществующий объект. Если мы попытаемся получить доступ к любому ресурсу из этого Non-Existent Object, мы не должны получать ничего, это логически имеет смысл. Но практически языки программирования, такие как Java, будут создавать экземпляр класса NullPointerException и заполнять требуемую информацию в Object и вызывать при вызове.

Ответ 4

Нуль на самом деле является ссылкой на память ничто (следовательно, null). Все ссылки на объекты в коде являются указателями на места в памяти, где хранятся физические данные. Если объект имеет значение null, то он не имеет ссылки или ничего не указывает на память. Вот почему null не может использоваться ни для чего другого, кроме проверки того, является ли он нулевым.

Java будет генерировать нулевое исключение, когда предпринимается попытка манипулировать объектом, который не имеет ссылки на физическую память.

Ответ 5

Он выводит true, потому что null == null

Null просто ничего не значит.

Animal animal=null;

Определяет ссылку на объект Animal, но еще не привязан к одному, поэтому он ничего не указывает.

Если вы знакомы с C/С++, это похоже на установку указателя на NULL или nullptr.

Ответ 6

Когда объект установлен в null, то в основном он не имеет ссылки на память в JVM. Кроме того, сравнение == между двумя нулевыми объектами также даст истинное значение.

Ответ 7

В Java есть только один null. Во всех случаях это происходит одинаково, независимо от переменной и даже независимо от класса. Компилятор не позволяет сравнивать напрямую, но вы можете использовать:

String x = null;
ArrayList a = null;
if ((Object) x == (Object) a) {
  System.out.println("Do not have onther nulls, only ME");
}

Ответ 8

На уровне байткода есть инструкция нажимать "нуль" на локальный стек (а затем назначать его переменному слоту или полю).

Большинство виртуальных машин Java фактически используют реальные (машинные) указатели, назначенные нулевому значению. Поэтому, если они используются, они внутренне захватывают сигнал (SIGSEGV) и преобразуют его в NPE. Вы можете проверить это, отправив "kill -SEGV" на Java PID, он будет генерировать случайные NullPointerExceptions большую часть времени.