NullPointerException при назначении номеров - PullRequest
0 голосов
/ 07 сентября 2011

Происходит странная вещь, когда я выполняю следующий код:

private void doStuff(Long inLong) {
    long theNumber = inLong;

    /* ... */
}

Иногда я вижу исключение NullPointerException в журналах в строке назначения, и я не могу понять, почему это происходит.Есть идеи?

Ответы [ 6 ]

2 голосов
/ 07 сентября 2011

Для long theNumber = inLong; длинное значение inLong выбирается путем неявного вызова inLong.longValue().Это называется автоматической распаковкой (иногда более общей автоматической коробкой).Когда inLong имеет значение NULL, вы получаете NullPointerException, точно так же, как и любой другой метод с нулевым значением.

Поэтому вам следует подумать о некоторой альтернативе:

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

private void doStuff(Long inLong) {
  assert inLong != null; 
  long theNumber = inLong;
  /* ... */
} 

(или используйте Nonnull-Checker ).Если метод был общедоступным, и вы не можете быть уверены, что значение null не передано, лучше сделайте:

public void doStuff(Long inLong) {
  if (inLong == null) { throw new IllegalArgumentException(); } 
  long theNumber = inLong;
  /* ... */
} 

Если вам не нужны неопределенные значения и не используется значение в коллекции (или в любом другом универсальном параметре),вместо этого используйте метод private void doStuff(long inLong).Если вам нужен объект Long, вы, конечно, можете по-прежнему использовать параметр типа long и выполнять (авто) упаковку внутри doStuff, чтобы получить соответствующий объект Long.

Если выМне нужны неопределенные значения, вы должны проверить это и сделать то, что необходимо:

private void doStuff(Long inLong) {
  if (inLong == null) { 
    handleUndef(); 
  } else {
    long theNumber = inLong;
    /* ... */
  }
} 

Просто установить значение 0 вместо более сложного handleUndef(), на мой взгляд, сомнительно, потому что тогда вы могли бы иметьв первую очередь использовал параметр типа long (см. выше).

2 голосов
/ 07 сентября 2011

Вы прошли в ноль.Проверьте, что вы передаете.

1 голос
/ 07 сентября 2011

потому что inLong может быть нулевым и не будет автоматически отображаться на 0.
Я думаю, что вы хотите сделать, это:

theNumber = 0; // or Long.MIN_VALUE or Long.MAX_VALUE or whatever you prefer
if (inLong != null) {
    theNumber = inLong;
}
// ... 
1 голос
/ 07 сентября 2011

inLong, вероятно, null. Затем вы пытаетесь присвоить ссылку null и распаковать ее в примитивный тип.

0 голосов
/ 07 сентября 2011

если inLong равен нулю, то NPE - ожидаемое поведение.

long theNumber = inLong;

семантически эквивалентно

long theNumber = inLong.longValue();

, что должно сделать причину NPE очевидной.

0 голосов
/ 07 сентября 2011

Это потому, что параметр inLong равен нулю. Всякий раз, когда вы присваиваете объект Long переменной long, Java автоматически пытается распаковать его с правильным типом, но происходит сбой, если значение переменной Long равно нулю.

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

...