Хорошим местом для начала является JavaDocs . Они охватывают это:
Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
- Вызов метода экземпляра нулевого объекта.
- Доступ или изменение поля нулевого объекта.
- Выполнение длины null, как если бы это был массив.
- Доступ или изменение слотов с нулевым значением, как если бы это был массив.
- Бросать нуль, как если бы это было значение Throwable.
Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.
blockquote>Также, если вы попытаетесь использовать нулевую ссылку с
synchronized
, который также выдаст это исключение, за JLS :SynchronizedStatement: synchronized ( Expression ) Block
blockquote>
- В противном случае, если значение выражения равно null,
NullPointerException
.Как это исправить?
Итак, у вас есть
NullPointerException
. Как вы это исправите? Возьмем простой пример, который выдаетNullPointerException
:public class Printer { private String name; public void setName(String name) { this.name = name; } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer(); printer.print(); } }
Идентифицирует нулевые значения
. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:
Exception in thread "main" java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
Здесь мы видим, что исключение выбрано в строке 13 (в методе
printString
). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, чтоs
имеет значение null, а вызов методаlength
на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когдаs.length()
удаляется из метода.Трассировка, где эти значения взяты из
Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что
s
передается сprintString(name)
в методеprint()
, аthis.name
- null.Трассировка, где эти значения должны быть установлены
Где установлен
this.name
? В методеsetName(String)
. С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. Этого достаточно, чтобы дать нам решение: добавить вызов
printer.setName()
перед вызовомprinter.print()
.Другие исправления
Переменная может иметь значение по умолчанию (и
setName
может помешать ему установить значение null):private String name = "";
Либо метод
printString
может проверить значение null например:printString((name == null) ? "" : name);
Или вы можете создать класс, чтобы
name
всегда имел ненулевое значение :public class Printer { private final String name; public Printer(String name) { this.name = Objects.requireNonNull(name); } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer("123"); printer.print(); } }
См. также:
Я все еще не могу найти проблему
Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).
Мой совет:
paster create
(см. http://pythonpaste.org ) создать Ваше начальное расположение каталога. В дополнение к PEP8 и easy_install, необходимо проверить virtualenv. Virtualenv позволяет Вам иметь несколько различных деревьев библиотеки Python. На работе мы используем virtualenv с загружающейся средой для быстрой установки разработки/продуктивной среды, где мы - все в синхронизации w.r.t версии библиотеки и т.д. Мы обычно координируем обновления библиотеки.
Существует несколько семейств компонентов Python.
материал, который идет с Python. Это заботится о себе.
материал, который Вы получили с easy_install. Это, также, заботится о себе.
пакеты, что необходимо было получить некоторый другой путь, или как TARballs или как контроль SVN. Создайте Components
папка. Поместите загрузки или SVN's там сначала. Каждый Раз. Сделайте установки оттуда.
пакеты, что Вы записали, что являются допускающими повторное использование. Я имею Projects
папка с каждым проектом в той папке. Если проект является очень допускающей повторное использование вещью, он имеет setup.py
, и я на самом деле выполняю установку, как будто я загрузил его. У меня нет многих из них, но некоторых. Некоторые из них могли бы стать проектами с открытым исходным кодом.
заключительные приложения Вы пишете. У меня есть папка в Projects
с каждым из этих приложений верхнего уровня. Они - обычно большие, хаотичные вещи (как сайты Django) и не имеют setup.py
. Почему? Они часто довольно сложны только с несколькими установками сервера для управления, и каждая из тех установок сервера уникальна. Они обычно полагаются PYTHONPATH
для идентификации их частей.
Уведомление общая тема. Или они - Компоненты, которые Вы загрузили, или они - Проекты, Вы продолжаете работать.
кроме того, я разделяю это (до степени) от клиента. У меня есть основной каталог папок Client, каждая из которых имеет Проекты и каждый проект, имеет Продажи и Доставку. Не все проекты имеют обе продажи и доставку.
"Модули" страница документации Python является полезным руководством по организации кода, конкретно разделы "пакетов"
Я сохраняю весь источник для своих пакетов внутри ~/Packages/, и затем я делаю стандартную установку с "установкой python2.5 setup.py" на них. Это бросает в (для меня)/Library/Frameworks/Python/Versions/current/lib/python2.5/site-packages/. Для разработки моего собственного программного обеспечения у меня есть псевдонимы, настроенные для переключения между соединительной линией / ответвлений/1.0, и т.д., pre-prending на PYTHONPATH. (Я должен работать 'setup.py build_ext - оперативный' в каждом из этих каталогов, прежде чем они импортируют правильно.)
стоит отметить, что Python2.6 имеет каталог пакетов сайта в расчете на пользователя, который можно найти более удобным.
Мой совет состоит в том, чтобы попытаться поместить все в Ваш каталог (каталоги) пакетов сайта, если у Вас нет серьезного основания не к. И я стараюсь избегать easy_install, потому что я нахожу, что он ухаживает к хламу за моим sys.path с местоположениями яйца, но это - просто я. Некоторые люди находят это полезным.
, Если у Вас есть много программ, которые пользуются различными библиотеками, которые могут конфликтовать друг с другом, можно также хотеть проверить virtualenv.