Почему скобки необходимы в блоке catch в java?

В java, если нам нужно выполнить только один оператор после if или for, скобки не нужны. Мы можем написать:

if(condition)
  executeSingleStatement();

или

for(init;condition;incr)
  executeSingleStatement();

Но в случае блока catch, почему мы не можем опустить скобки? Почему это невозможно?

catch(Exception e)
   e.printStackTrace();

Поскольку в большинстве случаев мы, у меня есть только один оператор в блоке catch, который либо является e.printStackTrace() при тестировании, либо в протоколе.

Ответ 1

Это не проблема возможного или невозможного. Это просто решение для языка (синтаксиса).

Существует несколько вариантов реализации парсера Java-языка. Можно изменить источник парсера менее чем за один день и разрешить заключенные в ящик высказывания.

http://www.google.com/search?q=java+parser

Также обратите внимание на грамматику языка Java.

Ответ 2

Найдите учебник по построению компилятора и поищите неопределенность.

Учитывая, что в Java и большинстве других языков с ужасным синтаксисом, пробел лежит. Как вы интерпретируете:

try
try
stuff();
catch (FooException exc)
handle(exc);
catch (BarException exc)
handle(exc);
catch (BazException exc)
handle(exc);

Это:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    } catch (BarException exc) {
        handle(exc);
    }
} catch (BazException exc) {
    handle(exc);
}

Или:

try {
    try {
        stuff();
    } catch (FooException exc) {
        handle(exc);
    }
} catch (BarException exc) {
    handle(exc);
} catch (BazException exc) {
    handle(exc);
}

Устранить неопределенность, связав else с самым внутренним if. Мы хотим добавить более сложное усложнение, чтобы справиться с этим плохим стилем? Номер

Изменить: Там есть комментарий, который пример не охватывает catch. Было бы правильным странным решением потребовать скобки для try, но не для catch/finally. Но в любом случае для полноты рассмотрим следующий код.

try {
stuff();
} catch (FooException foo)
try {
handle(foo);
} catch (BarException bar)
handle(bar);
catch (BazException baz)
handle(baz);
finally
release();

Связаны ли catch из BazException и finally с внутренним или внешним try? Опять же, комитет по разработке языка мог бы добавить тонну грамматики для устранения неоднозначности, но опять-таки явный стиль побеждает. Моя работа в Sun/Oracle была бы немного проще, если бы язык был упрощен для повселокального использования явных скобок.

Ответ 3

Я не уверен, почему Java не позволяет этого, но, как правило, лучше использовать скобки, даже если есть только один оператор. Это облегчает чтение и расширение.

Вот связанный вопрос, который касается использования скобок или нет: Нужны ли фигурные скобки в однострочных операциях в JavaScript?

Ответ 4

Из Java Language Spec 3.0 - Если вы посмотрите на главу 14, это говорит о блоках и операторах. Блоки идентифицируются с помощью {и} и содержат много операторов. Try/catch/finally - это блоки, которые по спецификации языка должны быть сгруппированы в {}.

Ответ 5

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

Я помогаю себе, написав однострочные уловы только в одной строке:

catch (InvalidArgumentException e) { die (e.getMessage()); }
catch (Exception e)                { die (e); }

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

catch (CanNotPayAttentionToThatManBehindTheCurtainThrowableRuntimeExceptionWithMessageAndCouseContainItselfAnotherCourseAndMessage e) ...

Ответ 6

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

Тем не менее, я не думаю, что есть действительно ответ на ваш вопрос за пределами "того, как они его разработали".

Ответ 7

Вероятно унаследовано от С++. Не знаю, почему С++ это сделал. Смотрите мои мысли здесь: https://stackoverflow.com/info/6254595/how-do-you-use-the-return/6255489#6255489

Также стоит отметить, что {} упрощает грамматику, т.е. упрощает работу с языком. Оператор if является хорошим примером - удобство, которое вам нравится, не дешево.

Из-за двусмысленности, типа

if(c1) if(c2) A; else B;

interpretation 1 
if(c1)
    if(c2) 
        A;
    else 
        B;

interpretation 2 
if(c1)
    if(c2) 
        A;
else 
    B;

Грамматика if должна быть изменена для устранения двусмысленности. Предположим, что block требуется вместо произвольного statement, грамматика будет намного проще из-за наличия {}.

Таким образом, они просто чувствовали себя ленивыми.