Что такое NullPointerException, и как я фиксирую его?

210
задан Ziggy 26 May 2016 в 06:15
поделиться

5 ответов

Когда Вы объявляете ссылочную переменную (т.е. объект), Вы действительно создаете указатель на объект. Рассмотрите следующий код, где Вы объявляете переменную типа примитива int:

int x;
x = 10;

В этом примере, переменная x int, и Java инициализирует его к 0 для Вас. Когда Вы присваиваете ему значение 10 на второй строке, Ваше значение [1 110] записано в ячейку памяти, упомянутую [1 111].

, Но, когда Вы пытаетесь объявить ссылку тип , что-то другое происходит. Возьмите следующий код:

Integer num;
num = new Integer(10);

первая строка объявляет переменную, названную num, но она еще на самом деле не содержит примитивное значение. Вместо этого это содержит указатель (потому что тип Integer, который является ссылочным типом). Так как Вы еще не сказали, что указать на, Java устанавливает его на [1 114], что означает", я указываю ничто ".

Во второй строке, new ключевое слово используется для инстанцирования (или создать), объект типа Integer и переменной указателя num присвоен тому Integer объект.

Эти NullPointerException происходит, когда Вы объявляете переменную, но не создали объект. Таким образом, Вы указываете на что-то, что на самом деле не существует.

, При попытке разыменовать num ПРЕЖДЕ, ЧЕМ создать объект, Вы добираетесь NullPointerException. В большинстве тривиальных случаев компилятор поймает проблему и сообщит, что" num may not have been initialized", но иногда можно записать код, который непосредственно не создает объект.

, Например, у Вас может быть метод следующим образом:

public void doSomething(SomeObject obj) {
   //do something to obj
}

, В этом случае, Вы не создаете объект obj, а скорее предполагаете, что он был создан, перед doSomething() метод назвали. Отметьте, возможно назвать метод как это:

doSomething(null);

, В этом случае, obj null. Если метод предназначается, чтобы сделать что-то к переданному - в объекте, уместно бросить NullPointerException, потому что это - ошибка программиста, и программисту будет нужна та информация для отладки целей.

, С другой стороны, могут быть случаи, где цель метода не состоит в том, чтобы только воздействовать на переданный в объекте, и поэтому пустой параметр может быть приемлемым. В этом случае необходимо было бы проверить на пустой параметр и вести себя по-другому. Необходимо также объяснить это в документации. Например, doSomething() мог быть записан как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, , Как точно определить исключение & причина с помощью Отслеживания стека

3649
ответ дан 18 revs, 17 users 56% 23 November 2019 в 04:33
поделиться

NullPointerException с являются исключениями, которые происходят, когда Вы пытаетесь использовать ссылку, которая не указывает ни на какое местоположение в памяти (пустой указатель), как будто это ссылалось на объект. Вызов метода на нулевой ссылке или попытка получить доступ к полю нулевой ссылки инициируют NullPointerException. Это наиболее распространенные, но другие пути, перечислены на NullPointerException javadoc страница.

, Вероятно, самый быстрый пример кода я мог придумать для иллюстрирования NullPointerException, будет:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

На первой строке в main, я явно устанавливаю Object ссылка obj равный null. Это означает, что у меня есть ссылка, но она не указывает ни на какой объект. После этого я пытаюсь рассматривать ссылку, как будто она указывает на объект путем вызова метода на нем. Это приводит к NullPointerException, потому что нет никакого кода для выполнения в месте, на которое указывает ссылка.

(Это - техническая особенность, но я думаю, что она переносит упоминание: ссылка, которая указывает на пустой указатель, не является тем же как указателем C, который указывает на недопустимую ячейку памяти. Нулевой указатель буквально не указывает нигде , который тонко отличается, чем указывать на местоположение, которое, оказывается, недопустимо.)

852
ответ дан 8 revs, 5 users 74% 23 November 2019 в 04:33
поделиться

Это похоже на Вас, пытаются получить доступ к объекту, который является null. Рассмотрите ниже примера:

TypeA objA;

В это время Вы имеете всего , объявил этот объект, но не инициализированный или инстанцировал . И каждый раз, когда Вы пытаетесь получить доступ к любому свойству или методу в нем, оно бросит NullPointerException, который имеет смысл.

Посмотрите это ниже примера также:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
414
ответ дан 5 revs, 5 users 38% 23 November 2019 в 04:33
поделиться

null указатель является тем, который не указывает на нигде. При разыменовании указателя p Вы говорите, "дают мне данные в местоположении, сохраненном в "p". Когда p null указатель, местоположение, сохраненное в p, nowhere, Вы говорите, "не дают мне данные в местоположении 'нигде'". Очевидно, это не может сделать этого, таким образом, это бросает null pointer exception.

В целом, это - потому что что-то не было инициализировано правильно.

324
ответ дан 5 revs, 5 users 50% 23 November 2019 в 04:33
поделиться

В Java все переменные, которые Вы объявляете, являются на самом деле "ссылками" на объекты (или примитивы) а не сами объекты.

, Когда Вы пытаетесь выполнить один метод объекта, ссылка спрашивает живущий объект выполнить тот метод. Но если ссылка ссылается на ПУСТОЙ УКАЗАТЕЛЬ (ничто, нуль, пусто, nada) тогда нет никакого способа, которым выполняется метод. Тогда время выполнения сообщило это путем броска NullPointerException.

Ваша ссылка "указывает" на пустой указатель, таким образом "Пустой указатель-> Указатель".

объектные жизни в пространстве памяти VM и единственном способе получить доступ к нему использует this ссылки. Возьмите этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И на другом месте в Вашем коде:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важная вещь знать - когда больше нет ссылок на объект (в примере, выше когда reference и otherReference обе точки к пустому указателю) тогда объект "недостижим". Нет никакого способа, которым мы можем работать с ним, таким образом, этот объект готов быть собранным "мусор", и в какой-то момент, VM освободит память, используемую этим объектом, и выделит другого.

300
ответ дан 4 revs, 4 users 79% 23 November 2019 в 04:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: