Как отловить исключение, вызванное отсутствием объекта в Java? - PullRequest
2 голосов
/ 30 сентября 2011

У меня очень простой метод:

public int getScore() {
    return game.gameWindow.userBestScore;
}

Проблема в том, что может случиться так, что game объект или gameWindow не существует. Я не хочу получать исключение нулевого указателя. Как правильно его поймать? Могу ли я сделать это следующим образом:

   public int getScore() {
         try{
             return game.gameWindow.userBestScore;
          } catch(NullPointerException e){
              return -1;
          }
   }

Ответы [ 6 ]

12 голосов
/ 30 сентября 2011

Не поймать NullPointerException.

A NullPointerException является признаком того, что ваш код не соответствует какому-либо контракту. Если возможно, что game может быть null, то вам нужно сделать явный тест:

if(game != null) {
   ...
}

else {
   ...
}

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

assert game != null;
...

Что больше всего беспокоит, так это то, что game кажется частным членом вашего класса. В этом случае game, вероятно, не должно быть null (хотя бывают случаи, когда это может произойти). Вы правильно инициализируете это в своем конструкторе? Я бы сказал, что первое, что вы должны сделать, это убедиться, что game правильно инициализируется. В противном случае ваш код будет засорен ненужными null -проверками. Например, что если gameWindow в классе Game не инициализирован должным образом? Для этого вам потребуется еще одна проверка null:

if(game !== null && game.gameWindow != null) {
   ...
}

else {
   ...
}

Итак, вы должны сначала убедиться, что приватные члены вашего объекта инициализируются правильно. Если они есть, и оказывается, что для game есть действительный вариант использования null, то вам понадобится явная проверка null-. Всегда лучше проверить на null, чем поймать NullPointerException. Кроме того факта, что исключения не должны использоваться для управления потоком вашей бизнес-логики, что, если допустимый NullPointerException (из-за ошибки программирования) был сгенерирован где-то в цепочке? Теперь ваш catch поймает это, и вы не будете знать об этом; это может привести к некоторым действительно неприятным и труднодоступным ошибкам.

2 голосов
/ 30 сентября 2011
public int getScore() {
    return ((game == null || game.gameWindow == null) ? -1 : game.gameWindow.userBestScore);
}
2 голосов
/ 30 сентября 2011

Проверьте, являются ли переменные null, как показано ниже:

public int getScore() {
    if(game == null || game.gameWindow == null){
        return -1;
    }
    return game.gameWindow.userBestScore;
}
2 голосов
/ 30 сентября 2011

Вы можете сделать это.Вы также можете проверить, являются ли game и gameWindow пустыми, прежде чем пытаться получить доступ к userBestScore.

if(game != null && game.gameWindow != null)
    return game.gameWindow.userBestScore
1 голос
/ 30 сентября 2011

Вы можете сделать это.ИЛИ вы можете проверить на нулевое значение, прежде чем разыменовывать эти объекты и предпринимать соответствующие действия без исключения.Это будет более эффективно.

Реальный вопрос, который вы должны задать, заключается в следующем: с какой стати у объекта могут быть нулевые ссылки для частных членов данных?Вы не строите свои объекты должным образом.Объект должен быть правильно инициализирован и на 100% готов к работе после его создания.В противном случае вы в конечном итоге будете вынуждены проявлять излишнюю оборону в своем коде.

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

Избегайте исключения как можно больше.Обработка известных проблем - лучший способ, чем генерирование исключений.

В некоторых случаях, когда вам нужно выполнить нулевую проверку.Вероятно, перед вызовом метода getScore (), потому что не имеет смысла вызывать этот метод, если game или windowWindow имеет значение null.

if (game != null && gameWindow != null)
{
    int score = getScore();
}

ИЛИ

public int getScore() 
{
    if (game != null && gameWindow != null)
    {
       return game.gameWindow.userBestScore;
    }
    else
    {
        return -1;
    }
}

Не выполнять повторные проверки на нуль.

...