Не удается запустить приложение для Android. Попытка вызвать виртуальный метод по ссылке нулевого объекта [duplicate]

Вы можете использовать libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // create the mail
$m->From( $_POST['form'] );
$m->To( $_POST['to'] );
$m->Subject( $_POST['subject'] );
$m->Body( $_POST['body'] );
$m->Cc( $_POST['cc']);
$m->Priority(4);
//  attach a file of type image/gif to be displayed in the message if possible
$m->Attach( "/home/leo/toto.gif", "image/gif", "inline" );
$m->Send(); // send the mail
echo "Mail was sent:"
echo $m->Get(); // show the mail source

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

12 ответов

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

int x;
x = 10;

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

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

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

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

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

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
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

3217
ответ дан 16 revs, 14 users 63% 21 August 2018 в 03:12
поделиться
  • 1
    «Лучший способ избежать этого исключения - всегда проверять значение null, когда вы сами не создали объект. & quot; Если вызывающий абонент пропускает значение null, но значение null не является допустимым аргументом для метода, тогда правильное исключение исключений для вызывающего, потому что это ошибка вызывающего абонента. Бесшумное игнорирование недопустимого ввода и ничего не делает в методе - крайне плохой совет, потому что он скрывает проблему. – Boann 29 July 2014 в 14:32
  • 2
    Я бы добавил замечание об этом сообщении, объяснив, что даже присвоения примитивов могут вызывать NPE при использовании автобоксинга: int a=b может вызывать NPE, если b является Integer. Бывают случаи, когда это запутывает для отладки. – Simon Fischer 26 September 2014 в 20:45
  • 3
    Можно ли захватить NPE, выброшенную webapp из веб-браузера, как это будет отображаться в источнике страницы просмотра из веб-браузера. – Sid 13 April 2015 в 14:51
  • 4
    Да проверьте, равен ли объект нулю null, прежде чем вы вызовете на нем метод или попытаетесь получить доступ к переменной, которую он может иметь. Несколько раз структурирование кода может помочь исключить исключение null-указателя. например, при проверке входной строки с постоянной строкой вы должны начинать с константной строки, как здесь: if («SomeString» .equals (inputString)) {} // даже если inputString не имеет значения, не генерируется исключение. Таким образом, есть множество вещей, которые вы можете сделать, чтобы попытаться быть в безопасности. – Rose 11 November 2015 в 05:39
  • 5
    Дополнительным способом избежать NullPointerException проблем в вашем коде является использование аннотаций @Nullable и @NotNull. Следующий ответ содержит дополнительную информацию об этом. Хотя этот ответ является специфическим для IntelliJ IDE, он также применим и к другим инструментам, как это показано в комментариях. (BTW Мне не разрешено напрямую редактировать этот ответ, возможно, автор может добавить его?) – Arjan Mels 3 January 2016 в 19:17
438
ответ дан 10 revs, 6 users 87% 21 August 2018 в 03:12
поделиться

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}
247
ответ дан 2 revs, 2 users 97% 21 August 2018 в 03:12
поделиться
  • 1
    операция на неинициализированном объекте на уровне экземпляра (а не на уровне класса) приведет к исключению NullPointerException. операция должна быть конкретной. если операция находится на уровне класса, говоря о вызове статического метода на неинициализированном объекте, тогда он не будет генерировать исключение NullPointerException. Даже примитивные объекты класса-оболочки генерируют исключение NullPointerException. – Shailendra Singh 8 July 2016 в 15:20
  • 2
  • 3
    @ tomj0101 Я не совсем понимаю, почему вы сделали этот комментарий ... Но к вашему второму пункту шаблон перед Optional должен был вернуть значение null. Ключевое слово в порядке. Знать, как защищаться от него, крайне важно. Это предлагает одно общее его появление и способы его смягчения. – Makoto 4 December 2017 в 06:54
  • 4
    NullPointerException - это исключение run-time , которое не рекомендуется ловить, но вместо этого избегать его. – Shomu 29 May 2018 в 10:14
  • 5
    @Shomu: В какой момент я даже предполагаю, что его нужно поймать? – Makoto 29 May 2018 в 13:25

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

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

293
ответ дан 4 revs, 4 users 57% 21 August 2018 в 03:12
поделиться

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

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки 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 оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

257
ответ дан 4 revs, 4 users 79% 21 August 2018 в 03:12
поделиться

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

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

315
ответ дан 5 revs, 4 users 55% 21 August 2018 в 03:12
поделиться
  • 1
    Держите это просто, мне нравится этот ответ, добавьте это, если вы считаете правильным - доступ к неинициализированному атрибуту объекта – Emiliano 23 March 2016 в 14:06
  • 2
    @Emiliano - просто доступ к инициализированному атрибуту не вызывает NPE. Это то, что вы & gt; & gt; с неинициализированным значением атрибута, вызывающим NPE. – Stephen C 19 May 2016 в 06:57
  • 3
    – Dominique Unruh 18 September 2016 в 17:07
  • 4
    Если вам нужно больше случаев: 1) используя null в качестве цели блока synchronized, 2), используя null в качестве цели для switch и unboxing null. – Stephen C 23 October 2017 в 10:16

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

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
277
ответ дан 5 revs, 4 users 61% 21 August 2018 в 03:12
поделиться
  • 1
    Хотя это хороший пример, могу ли я спросить, что он добавляет к вопросу, который еще не охвачен всеми другими ответами? – Mysticial 24 September 2013 в 07:20
  • 2
    Просто нецелесообразно использовать слово «неинициализированный». Вот. Пример, который вы показали, фактически «инициализирован» и инициализирован нулевым значением. Для неинициализированных переменных компилятор вам будет жаловаться. – Adrian Shum 24 September 2013 в 07:32
  • 3
    NPE может быть индикатором того, что вы используете неинициализированное поле. Это может быть индикатором того, что вы делаете другие вещи. Упрощение к одной причине, подобной этой, не помогает кому-то решить проблемы NPE ... если фактическая причина не та. – Stephen C 27 May 2015 в 13:35

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).
280
ответ дан 5 revs, 4 users 68% 21 August 2018 в 03:12
поделиться
  • 1
    В проектах j2ee исключение Nullpointer очень распространено. Некоторые ссылочные переменные случаев получили нулевые значения. Поэтому вы должны проверить правильность инициализации правильно. И во время условного оператора вы всегда должны проверить, что флаг или ссылка содержит нуль или не нравится: - if (flag! = 0) {ur код, который использует флаг} – Amaresh Pattanayak 17 April 2015 в 12:58
  • 2
    – Jan Chimiak 5 March 2016 в 11:34
  • 3
    Прежде всего, нужно использовать объект с нулевым значением, вы должны проверить, является ли он нулевым, используя if (obj==null). Если он равен нулю, тогда вы также должны написать код для обработки. – Lakmal Vithanage 17 February 2017 в 07:52
  • 4
    IMO, предпочтительнее избегать возврата нулевых объектов в методах, когда это возможно, и использовать аннотацию, когда пустые входные параметры не разрешены, чтобы по контракту уменьшить количество'if (obj == null) 'в коде и улучшить читаемость кода. – L. G. 27 February 2017 в 10:43
  • 5
    Прочтите это ... прежде чем принимать эти «лучшие практики». как истина: satisfice.com/blog/archives/27 – Stephen C 21 May 2017 в 07:52

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

TypeA objA;

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

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
366
ответ дан 5 revs, 5 users 38% 21 August 2018 в 03:12
поделиться

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

269
ответ дан 5 revs, 5 users 58% 21 August 2018 в 03:12
поделиться
  • 1
    Объявление примитивной переменной, такой как int, в Java не создает объект. – Michael Krause 15 November 2016 в 22:44
  • 2
    Исключение NullPointerException часто возникает при вызове метода экземпляра. Например, если вы объявляете ссылку, но не указываете на какой-либо экземпляр, исключение NullPointerException произойдет, когда вы вызовете его метод. например: YourClass ref = null; // или ref = anotherRef; // но anotherRef не указал ни одного экземпляра ref.someMethod (); // он будет вызывать исключение NullPointerException. Обычно исправляйте это следующим образом: перед вызовом метода определите, является ли ссылка нулевой. например: if (yourRef! = null) {yourRef.someMethod (); } – sunhang 28 July 2017 в 10:25
  • 3
    Или используйте захват исключений, например: try {yourRef.someMethod (); } catch (NullPointerException e) {// TODO} – sunhang 28 July 2017 в 10:25
612
ответ дан 7 revs, 5 users 89% 21 August 2018 в 03:12
поделиться

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

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

public class Example {

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

}

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

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

758
ответ дан 8 revs, 5 users 74% 21 August 2018 в 03:12
поделиться
  • 1
    Я понял все, что вы там написали, но только потому, что я некоторое время программировал и знаю, что такое «указатель» и «ссылка» (и что такое нуль, если на то пошло). Когда я пытаюсь погрузиться прямо в такие объяснения, мои ученики смотрят на меня, потому что не хватает фона. – mmr 20 February 2009 в 05:06
  • 2
    @mmr: Спасибо за отзывы, вы действуете правильно. В Интернете сложно судить, где кто-то, и на каком уровне можно начать объяснение. Я попробую пересмотреть это снова. – Bill the Lizard 20 February 2009 в 05:32
  • 3
    Более распространенный способ получить исключение NullPointerException на практике - это забыть явно инициализировать переменную-член чем-то, кроме null, прежде чем использовать его, , как это . С локальными переменными компилятор поймал бы эту ошибку, но в этом случае это не так. Может быть, это послужит полезным дополнением к вашему ответу? – Ilmari Karonen 18 January 2014 в 11:28
  • 4
    @EJP "Нулевой указатель буквально не указывает нигде ... & quot; – Bill the Lizard 13 June 2015 в 03:06
  • 5
    @EJP Это именно то, что указывает этот параграф. – Bill the Lizard 11 August 2015 в 10:59
Другие вопросы по тегам:

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