Узнайте, какая переменная генерирует исключение NullPointerException программно - PullRequest
21 голосов
/ 19 апреля 2010

Я знаю, что могу узнать, является ли переменная нулевой в Java, используя следующие методы:

  • если (var==null) -> слишком много работы
  • try { ... } catch (NullPointerException e) { ...} -> это говорит мне, какая строка вызывает исключение
  • использование отладчика -> вручную, слишком медленно

Рассмотрим эту строку кода:

if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0)  {

Я хотел бы знать, существует ли общий способ программно выяснить, какая переменная (не только строка) выдает исключение NullPointerException в определенной области кода. В примере, зная, что

Ответы [ 7 ]

27 голосов
/ 19 апреля 2010

Так как возможно вызвать исключение нулевого указателя, даже не включая переменную:

throw new NullPointerException();

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

Лучше всего ставить как можно меньше операторов в каждой строке, чтобы стало понятно, что вызвало исключение нулевого указателя. Рассмотрите возможность рефакторинга вашего кода в вопросе, чтобы он выглядел примерно так:

List items = this.superSL.items;
String name = items.get(name);
String source = name.getSource();
if (source.compareTo(VIsualShoppingList.Source_EXTRA) == 0)  {
    // ...
}

Это больше строк кода, чтобы быть уверенным. Но он также более читабелен и удобен в обслуживании.

6 голосов
/ 19 апреля 2010

Извините, нет, не существует простого программного способа определить, какая переменная или вызов метода является источником исключения. Вы можете использовать что-то вроде Аспектно-ориентированное программирование (AOP) , например AspectJ , но это не присуще языку и обычно не включается в программу просто для целей отладки.

  • if (var==null) -> too much work
  • try { } catch() { }
  • Debugger

Я знаю, что вы не хотите это слышать, но это просто стоимость ведения бизнеса.

if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0)  {

Необычно видеть так много связанных друг с другом вызовов методов. Я полагаю, что вам лучше всего привыкнуть разбивать их больше - не обязательно до 1 звонка на линию, но меньше, чем это. Почему?

1) Correctness - допустимо ли в проекте для одного из этих вызовов вернуть значение null? Если это так, вам следует разобраться с этим, проверить его и надлежащим образом обработать.

2) Understandability - будущим сопровождающим (включая будущие вы ) будет легче понять, если вы используете промежуточные, хорошо названные переменные, чтобы прояснить, что происходит в этой строке.

3) Efficiency - обычно, когда вы углубляетесь в график (объединяя серию вызовов методов), вполне вероятно, что вам потребуется вернуться туда позже. Захват этого промежуточного значения в промежуточной переменной означает избегание повторного вызова одного или нескольких методов.

4) Debugging - как показывает ваш вопрос, разбиение сложной строки таким образом упрощает отладку. сузив возможный источник исключения.

2 голосов
/ 19 апреля 2010

Что вы подразумеваете под "использованием отладчика -> вручную, слишком медленно"? Если ваш код правильно структурирован, то в одной строке будет использоваться не более двух-трех переменных. Это так медленно, чтобы проверить их? У вас нет NullPointers каждую минуту.

1 голос
/ 19 апреля 2010

Я думаю, вы должны заметить Закон о параметрах .

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

1 голос
/ 19 апреля 2010

Я знаю, что вы предположили, что (var==null) - это слишком много работы, но, как сказал Мигель в комментариях, я бы с этим согласился.

0 голосов
/ 06 июля 2013

Что действительно хорошо для меня сработало, так это поймать исключение, при котором он обычно генерируется, и затем использовать Log, чтобы посмотреть, имеют ли какие-либо из них значения 'null'.

Мой код:

 try {
                 if (description_visible) advice_title_cur.setText(all_title_array[pos]);
                 else advice_title_cur.setText(all_title_array[pos] + "...");

             } catch (NullPointerException e) {
                 e.printStackTrace();
                 Log.e("My name", "description_visible " + description_visible);
                 Log.e("My name", "advice_title_cur " + advice_title_cur);
                 Log.e("My name", "all_title_array " + all_title_array);
                 Log.e("My name", "pos " + pos);
             }
0 голосов
/ 31 июля 2012

К сожалению, Java не покажет вам имя переменной или точную позицию ошибки, кроме номера строки. Однако если вы используете Eclipse, вы можете использовать аннулируемые аннотации, см., Например, http://www.fosslc.org/drupal/content/bye-bye-npe. См. Какую аннотацию @NotNull Java следует использовать? для других систем аннотаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...