Хорошим местом для начала является 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 ).
Я думаю, что это зависит от среды, в которой Вы находите себя. Если Вы *, отклоняют человека, то знание awk
является Хорошей Вещью. Единственная другая среда сценариев, которая может быть найдена на фактически каждом *, отклоняет, sh
. Таким образом, в то время как grep
, sed,
и т.д. может, конечно, заменить awk
на современной господствующей тенденции linux
дистрибутив, когда Вы перемещаетесь в более экзотические системы, знание немного awk
будет Реальным Удобный.
awk
может также использоваться для больше, чем просто обработки текста. Например, один из моих супервизоров пишет код астрономии в awk
- именно так крайне старая школа и , потрясающая , он. Назад в его дни, это был лучший инструмент для задания... и теперь даже при том, что его студенты как я используют Python и что не, он придерживается того, что он знает и работает хорошо.
В закрытии, существует много старого кода, ударяющего во всем мире, знание немного awk
не собирается причинять боль. Это также сделает Вас лучше *, отклоняют человека:-)
Теперь, когда Perl портирован на в значительной степени каждую значительную платформу, я сказал бы, что это не стоит того. Это более универсально, чем sed и awk вместе. Что касается авторазделения, можно сделать это в жемчуге как это:
perl -F':' -ane 'print $F[3],"\n";' /etc/passwd
РЕДАКТИРОВАНИЕ: Вы могли бы все еще хотеть стать несколько познакомившими с awk, потому что некоторые другие инструменты основаны на его философии основанных на шаблоне действий (например, DTrace на Солярисе).
Я сказал бы, что существует. Для простого материала AWK намного легче на неопытном системном администраторе / разработчик, чем Python. Можно изучить немного AWK и сделать много вещей, узнав, что Python означает учить совершенно новый язык (да, я знаю, что AWK является языком, смысл также).
Perl мог бы быть в состоянии сделать много вещей, которые AWK может сделать, но предложил выбор в этот день и возраст, я выберу Python здесь. Таким образом да, необходимо изучить AWK. но изучите Python также:-)
Нет.
Даже при том, что это могло бы быть интересно, можно сделать все, что awk может сделать использование другого, более мощные инструменты, такие как Perl.
Проводят Ваше время, изучая те более мощные инструменты - и только случайно берут некоторый awk по пути.
Я сказал бы, что это, вероятно, больше не стоит того. Я время от времени использую его в качестве намного большего количества универсального потокового редактора, чем sed с ищущими включенными способностями, но если бы Вы являетесь опытными с Python, я не знаю задачу, которую Вы были бы в состоянии закончить, это намного быстрее для компенсации в течение времени должно было изучить awk.
следующая команда является, вероятно, единственной, для которой я использовал awk за прошлые два года (это производит чистку полуудаленных пакетов от моих систем Debian/Ubuntu):
$ dpkg -l|awk '/^rc/ {print $2}'|xargs sudo dpkg -P
Конечно: я работаю в среде, где единственные доступные языки: (некоторый поганый язык, который генерирует КОБОЛ, OMG, OMG), удар (старая версия), жемчуг (я еще не осваиваю его), sed, awk, и некоторые другие утилиты командной строки. Знание awk
сохранило меня несколько часов (и генерировал несколько задач обработки текста от моего collegaues - они прибывают ко мне по крайней мере три раза в день).
Полезно главным образом, если необходимо иногда анализировать файлы журнала для данных или вывода программ, в то время как сценарии оболочки, потому что очень легко достигнуть в awk этого, которое взяло бы Вас немного больше строк кода в Python.
Это, конечно, имеет больше силы, чем это, но это, кажется, задачи, для которых большинство людей использует его.
Computerworld недавно сделал интервью с Alfred V. Aho (один из трех создателей AWK) о AWK. Это - довольно интересное чтение. Таким образом, возможно, Вы найдете некоторые подсказки в нем, почему это - хорошая идея, изучают AWK.
Изучение AWK было неоценимо для меня в моем последнем контракте, работающем над встроенной системой Linux, в которой не были установлены ни Perl, ни большинство других языков сценариев.
Большая часть awk лайнеры могут быть достигнуты с Perl лайнеры - если Вы принимаете решение войти в Perl одно мышление лайнера. Или, просто используйте Perl три лайнера:)
при поддержании сценариев оболочки, записанных кем-то, кому понравился awk, тогда ясно, Вы собираетесь должны изучить awk.
, Даже если нет никакой практической потребности, если Вы уже знаете regex, не займет много времени брать основы, и это интересно видеть, как вещи были разработаны тогда. Это довольно изящно.
Если Вы уже знаете и используете sed, Вы могли бы также взять, по крайней мере, немного awk. Они могут быть переданы по каналу вместе для некоторых довольно мощных приемов. Всегда производит на аудиторию впечатление.
Я иногда использую AWK для контакта с HTML. Например, этот код переводит таблицы в файлы CSV:
BEGIN {s=""; FS="n"}
/<td/ { gsub(/<[^>]*>/, ""); s=(s ", " $1);}
/<tr|<TR/ { print s; s="" }
, Который является большим, если Вы - анализ экранных данных. На самом деле могло бы иметь место, что я люблю AWK, потому что это позволяет мне создавать неверное решение проблем так быстро:) [еще 111] примеры . Это также упоминается в Jon Bentley, прекрасном Жемчуг Программирования .
Я действительно использую awk время от времени. Это хорошо для очень простой текстовой перестановки посреди конвейера; это заполняет очень узкую нишу прямо между не необходимостью в нем вообще и необходимостью выкрикнуть Perl/Python/whatever.
я не советовал бы провести много времени на нем, но это могло бы пригодиться для знания основ синтаксиса - по крайней мере, достаточно, что можно консультироваться, руководство быстро должно Вы когда-либо хотеть использовать его.
Единственной причиной, которую я использую awk
, является авторазделение:
awk '{print $3}' < file.in
Это печатает третье разграниченное пробелом поле в file.in
. Это немного легче, чем:
tr -s ' ' < file.in | cut -d' ' -f3
Я думаю, что awk является большим, если Ваш файл содержит столбцы/поля . Я использую его при обработке/анализе конкретного столбца в многостолбцовом файле. Или если я хочу добавить/удалить конкретный столбец (столбцы).
, например,
awk -F \t '{ if ($2 > $3) print; }' <filename>
распечатает, только если 2-е значение столбца на вкладке отделилось, файл больше, чем 3-е значение столбца.
, Конечно, я мог использовать Perl или Python, но awk делает его настолько более простым с краткой однострочной командой.
Также изучение awk является довольно недорогим. Можно изучить awk основы меньше чем через час, таким образом, это не столько же усилия сколько изучение никакого другого программирования/языка сценариев.
Если Вы быстро изучаете основы awk, можно действительно сделать удивительные вещи на командной строке.
Но настоящая причина для изучения awk состоит в том, чтобы иметь оправдание прочитать превосходную книгу Язык программирования AWK его авторами Aho, Kernighan и Weinberger. Вы думали бы с имени, что оно просто преподает Вам awk. На самом деле это - только начало. Запуск в обширный массив проблем, которыми можно заняться, после того как каждый использует краткий язык сценариев, который делает обработку строк легкой — и awk, был одним из первых — это продолжает учить читателя, как реализовать базу данных, синтаксический анализатор, интерпретатор, и (если не изменяет память, меня) компилятор для маленького определенного для проекта языка программирования! Если бы только они также запрограммировали операционную систему в качестве примера с помощью awk, то книга была бы довольно полным введением обзора в информатику!
Заметно очиститесь и краткий, как исходная книга языка C, это также - замечательный пример дружественной технической сделанной правильно записи. Даже индекс является частью мастерства.
Awk? Если Вы будете знать это, то Вы будете использовать его в командной строке иногда, но для чего-либо большего Вы будете чувствовать себя захваченными, не могущими получить доступ к более широким функциям Вашей системы и Интернета, к которому что-то как Python обеспечивает доступ. Но книга? Вы будете всегда радоваться, что читаете его!