Я писал код и заметил закономерность в обработке исключений, которая заставила меня задуматься:
try{
// do stuff... throws JMS, Create and NamingException
} catch (NamingException e) {
log1(e);
rollback();
doSomething(e)
} catch (CreateException e) {
log1(e);
rollback();
doSomething(e)
}
Где JMSException будет обрабатывать где-то в стеке.
Было бы просто написать:
try{
// do stuff... throws JMS, Create and NamingException
} catch Exception[NamingException, CreateException] e) {
log1(e);
rollback();
doSomething(e)
}
вместо того, чтобы помещать его в вспомогательный метод:
try{
// do stuff... throws JMS, Create and NamingException
} catch (NamingException e) {
helper_handleError1(e)
} catch (CreateException e) {
helper_handleError1(e)
}
Обратите внимание, что я хочу распространить трассировку стека исходного JMSException, и мне не «хочется» создавать новое исключение JMSException с третьим предложением catch :)
Какие-нибудь крутые? Это крайняя ситуация, которая только загрязняет синтаксис Java, или это просто классная вещь, которую нужно добавить?




Я бы хотел, чтобы можно было выполнить сопоставление с образцом для типа исключения в качестве синтаксического дополнения. Что-то типа
try {
...
} catch ((IOException && !FileNotFoundException) || IllegalArgumentException ) {
... handle it
}
Я предлагаю использовать идиому «Execute Around».
Я не думаю, что это действительно подходит его делу; он хочет, чтобы хотя бы одно исключение ускользнуло и распространялось вверх по цепочке.
Ави: Хороший вопрос. stackoverflow.com/questions/341971/…
Грег: Я не вижу этого в исходном вопросе, и все равно не вижу в этом проблемы.
Попробуй это:
try {
...
} catch ( Exception e) {
if typeof(e) not in ('MyException', 'SpecialException') {
throw e
}
doSomething()
}
(псевдокод)
Он выглядит хорошо как псевдокод, но не очень практичен при преобразовании в реальный код; (
На первом месте,
} catch Exception[NamingException, CreateException] e) {
не хватает символа '(' char.
Во-вторых, почему «Exception [NamingException, CreateException] e», а не просто «[NamingException, CreateException] e»?
Идея может быть приятной, но требует доработки. Например, предположим, что я объявляю класс MyException с функцией doYellow () и класс OtherException с функцией doYellow (). Разрешена ли такая функция (учитывая, что в суперклассе нет функции doYellow ())? Если да, то можно ли было бы объявить doYellow () только для одного из них? Это то, что «Исключение» перед символами []? Также предположим, что есть это объявление:
void doYellow(NamingException e);
void doYellow(CreateException e);
(обратите внимание, что это разные функции) будет ли разрешено называться?
Вам действительно стоит предоставить более подробную информацию. Однако в некоторых случаях это может быть полезно (это не редкость).
Они рассматривают возможность расширения этого типа для Java 7.
Другой способ сделать.
Преобразуйте исключение низкого уровня в собственное исключение высокого уровня и обработайте его.
try{
try{
// do stuff... throws JMS, Create and NamingException
} catch (NamingException e) {
throw new MyException(e);
} catch (CreateException e) {
throw new MyException(e);
}
} catch (MyException e) {
// something on e or e.getCause();
}
Почему не просто
try
{
// do stuff... throws JMS, Create and NamingException
} catch (JMSException e)
{
if (e instanceof CreateException || e instanceof NamingExcption)
{
log1(e);
rollback();
doSomething(e);
}
else
throw e;
}
Иногда вы можете не захотеть этого делать по двум причинам. 1. У них может не быть одного и того же общего родительского исключения. 2. Класс повторной генерации не может быть проверенным исключением, объявленным в интерфейсе.
Пока мы придумываем синтаксис, вот каким я хотел бы это видеть:
try
{
// do stuff ...
}
catch (NamingException e)
catch (CreateException e)
{
log1(e);
rollback();
doSoemthing(e);
}
Подобно провалу оператора switch или блока C# using. Конечно, здесь проблема с дважды объявленной переменной e, но я думаю, что что-то можно решить.
Что такое идиома «Казнь вокруг»?