Java обработка ошибок для исключения нулевого указателя в массиве - PullRequest
1 голос
/ 06 февраля 2020

Извините, если это повторяющийся вопрос, я провел поиск и не смог найти свой конкретный c сценарий.

Мне было интересно, могу ли я получить какой-нибудь совет относительно лучшего способа справиться с нулем ошибки исключения с функциями, которые пытаются вернуть объект из ArrayList по идентификатору, если проанализированный идентификатор не найден в индексе ArrayList.

У меня есть класс Project, в котором есть объекты ArrayList of Task:

private ArrayList<Task> tasks = new ArrayList<Task>();

и у меня есть функция get в классе Project, чтобы попытаться вернуть задачу по ее идентификатору из ArrayList:

public Task getTask(int id)  {
    if(id > 0 && id <= tasks.size()) {
        for(Task task : tasks) {
            if(task.getID() == id) {
                return task;
            }
        }
    } else { 
        Globals.log("Couldt find Task with ID of: " + id + " in Project: " + title); 
    }
    return null;
}

Когда я пытаюсь вызвать функцию в Задача, получая задачу из идентификатора, если идентификатор задачи не существует в индексе ArrayList, естественно, я получаю сообщение об ошибке исключения NULL, например, если нет задачи с идентификатором 15, этот код завершится с нулем указатель на исключение:

project.getTask(15).addTag("Test");

У меня вопрос, могу ли я выполнить некоторую обработку ошибок в функции getTask(int id) для регистрации ошибки до сбоя программы?

Я пытался добавить try {} catch {} вокруг него, но он по-прежнему не запускает мою функцию Globals.log() до ее сбоя.

Добавление блока try {} catch {} работает, если я выполняю обработку ошибок в функции addTag(); в классе Task, но я бы предпочел не go выполнять все мои функции в классе Task и добавлять try {} catch {} к каждой функции.

Есть ли лучшее решение этой проблемы?

Ответы [ 4 ]

3 голосов
/ 06 февраля 2020

С java 8 вы можете использовать Optional в качестве типа возврата, если Task присутствует в возвращаемом массиве Optional с Task иначе пусто Optional

public Optional<Task> getTask(int id)  {
if(id > 0 && id <= tasks.size()) {
    for(Task task : tasks) {
        if(task.getID() == id) {
            return Optional.of(task);
        }
    }
} 

 Globals.log("Couldt find Task with ID of: " + id + " in Project: " + title); 

return Optional.empty();
}

И с Опционально Вы можете использовать ifPresent, избегая try-catch и null, проверьте также

project.getTask(15).ifPresent(t->t.addTag("test"));
1 голос
/ 06 февраля 2020

Я думаю Deadpool решил проблему NPE, но в вашем коде есть еще один небольшой недосмотр.

Если в случае, если идентификаторы не упорядочены последовательно, то ваша первая проверка if(id > 0 && id <= tasks.size()) вызовет проблемы, и их удаление будет хорошей идеей:

public Optional<Task> getTask(int id) {
    for (Task task : tasks) {
        if (task.getID() == id) {
            return Optional.of(task);
        }
    }

    Globals.log("Couldt find Task with ID of: " + id + " in Project: " + title);

    return Optional.empty();
}
0 голосов
/ 06 февраля 2020

Попробуйте это

Task taskObj=null;

        for(Task task : tasks) {
            if(task.getID() == id) {
                taskObj= task;
            }
        }
    if(taskObj!=null)
    { 
        return null;
    }else{
        Globals.log("Couldt find Task with ID of: " + id + " in Project: " + title); 
        return null;
    }
}

public void mainClass() {
   Task task = project.getTask(15);
   if (task != null) {
      task.addTag("Test");
   }
}
0 голосов
/ 06 февраля 2020

Не используйте try / catch в этом случае.

Вам необходимо проверить, возвращает ли метод getTask значение NULL, прежде чем использовать его следующим образом:

public void test() {
   Task task = project.getTask(15);
   if (task != null) {
      task.addTag("Test");
   }
}
...