Могу ли я перехватить несколько исключений Java в одном предложении catch?

Строка

a[:] = [i + 6 for i in a]

не сохранит никакой памяти. Сначала Python оценивает правую сторону, как указано в документации по языку :

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

blockquote>

В данном случае одиночный результат объект будет новым списком, а единственной целью в целевом списке будет a[:].

Мы могли бы заменить понимание списка выражением генератора:

a[:] = (i + 6 for i in a)

Теперь , правая часть вычисляет генератор вместо списка. Бенчмаркинг показывает, что это все еще медленнее, чем наивный

a = [i + 6 for i in a]

. Так действительно ли выражение генератора сохраняет память? На первый взгляд, вы можете подумать, что это так. Но вхождение в исходный код функции list_ass_slice() показывает, что это не так. Строка

v_as_SF = PySequence_Fast(v, "can only assign an iterable");

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

Мораль, по-видимому, в том, что самый простой подход является лучшим в любом отношении.

647
задан MultiplyByZer0 1 November 2018 в 20:16
поделиться

6 ответов

Это стало возможным начиная с Java 7. Синтаксис блока с несколькими отловами следующий:

try { 
  ...
} catch (IOException | SQLException ex) { 
  ...
}

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

Также обратите внимание, что вы не можете перехватить в одном блоке исключения ExceptionA и ExceptionB, если ExceptionB прямо или косвенно наследуется от ExceptionA. Компилятор будет жаловаться:

Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA
1081
ответ дан 22 November 2019 в 21:44
поделиться

В Java 7 вы можете определить несколько пунктов catch, например:

catch (IllegalArgumentException | SecurityException e)
{
    ...
}
23
ответ дан 22 November 2019 в 21:44
поделиться

Для kotlin это не возможно на данный момент, но они рассмотрели для добавления его: Источник
, Но на данный момент, просто немного приема:

try {
    // code
} catch(ex:Exception) {
    when(ex) {
        is SomeException,
        is AnotherException -> {
            // handle
        }
        else -> throw ex
    }
}
0
ответ дан 22 November 2019 в 21:44
поделиться

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

0
ответ дан 22 November 2019 в 21:44
поделиться

Нет, по одному на покупателя.

Вы можете перехватить суперкласс, например java.lang.Exception, если будете выполнять одно и то же действие во всех случаях.

try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
    e.printStackTrace();
}

Но, возможно, это не лучшая практика. Вы должны перехватывать исключение только тогда, когда у вас есть стратегия для его фактической обработки - а регистрация и повторное генерирование не являются «обработкой». Если у вас нет корректирующего действия, лучше добавить его в сигнатуру метода и позволить кому-то, кто может справиться с ситуацией.

15
ответ дан 22 November 2019 в 21:44
поделиться

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

try {
   ...
} catch (Exception e) {
   someCode();
}

В более распространенном случае, если RepositoryException - базовый класс, а PathNotFoundException - производный класс, то:

try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

Приведенный выше код будет ловить RepositoryException и PathNotFoundException для одного вида обработки исключений, а все остальные исключения будут объединены вместе. Начиная с Java 7, согласно ответу @OscarRyz выше:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}
14
ответ дан 22 November 2019 в 21:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: