Как создать блок try-catch, который продолжает вызывать метод объекта, пока не будет больше исключений для перехвата - PullRequest
1 голос
/ 20 апреля 2010

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

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

Ответы [ 4 ]

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

Это похоже на другие ответы, но без флага, который мне кажется беспорядочным. Однако я не совсем понимаю вопрос, поэтому просто выкидываю его на случай, если он будет полезен.

for (Item item : items) {
  while (true) {
    try {
      item.doSomething();
      break;
    } catch (MyException ex) {
      log.warn("Something failed.", ex);
    }
  }
}

Этот подход зависит от операции немеченого оператора break, который завершается внезапно и затем нормально завершает оператор while.


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

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

Итак, если метод генерирует несколько исключений, поймайте общего предка и продолжайте. Например, если метод выбрасывает java.io.EOFException или java.nio.channels.ClosedChannelException, вы можете просто поймать java.io.IOException, поскольку он является общим предком. (Вы также можете поймать java.lang.Exception или java.lang.Throwable по той же причине.) Повторный вызов метода при тех же условиях не даст вам дальнейших результатов.

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

for (Item item : items) {
  try {
    item.doSomething();
  } catch (Exception ex) { /* This could be any common ancestor. */
    log.warn("Something failed.", ex);
  }
}
2 голосов
/ 20 апреля 2010

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

Но если вы говорите о методе, который иногда генерирует исключения, а иногда нет, попробуйте что-то вроде этого:

boolean thrown = false;
do {
    try {
        thrown = false;
        method();
    }
    catch (Exception e) {
        thrown = true;
        // Handle as you like
    }
} (while thrown);
0 голосов
/ 20 апреля 2010

Это то, что я понимаю.

У вас есть метод объекта, который может выдать несколько исключений.

Что вы хотите сделать, это перехватить их все и перейти к следующему объекту в списке.

Это правильно?

Итак, это будет:

for( YourObject o : yourList ) {
    try {
       o.thatMethod();//invoke that risky method 
    } catch( SomeExceptionClass sec ) {
       // Do something with that exception
    } catch( SomeOtherExceptionClass soec ) {
       // Do something with that exception  
    } catch( YetAnotherxceptionClass yaec ) {
       // Do something with that exception
    } catch( OtherUnRelatedException oue ) {
       // Do something with that exception
    }
}

Когда вы делаете это, если вызов thatMethod() вызывает исключение, и это исключение перечислено в разделе catch, поток выполнения перейдет к этому исключению и после этого перейдет к обычному потоку ( цикл for и будет продолжен со следующего объекта)

Надеюсь, это то, что нужно. Для получения дополнительной информации читайте: Блок catch в разделе Учебное пособие по Java Основные классы

0 голосов
/ 20 апреля 2010

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

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

boolean exceptionCaught = false;
do {
    try {
        item.doSomething();
    } catch (MyException e) {
        exceptionCaught = true;
    }
} while (exceptionCaught);

Это терпит неудачу, потому что каждый раз, когда вы звоните item.doSomething(), оно будет выдавать исключение в одном и том же месте. Конечным результатом является бесконечный цикл.

Лучшее, что вы можете сделать с этим подходом, - захватить первое исключение для каждого item в списке.

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

class Item {
    ...
    void validate() {
        if (noHat) {
            throw new MyException("bad hat");
        }
        if (noPants) {
            throw new MyException("world-wide pants");
        }
    }
}

примерно так:

class Item {
    ...
    void isValid(List<MyException> errors) {
        boolean ok = true;
        if (noHat) {
            errors.add(new MyException("bad hat"));
            ok = false;
        }
        if (noPants) {
            errors.add(new MyException("world-wide pants"));
            ok = false;
        }
        return ok;
    }
}

Грязно, да! Вы можете воспринимать это по-разному, но такой стиль отчетов об ошибках всегда будет более сложным. Но я не думаю, что есть практический способ избежать беспорядка И захвата ВСЕХ ошибок проверки.

...