Стиль написания кода

Что бы сразу же был понятен вопрос, привожу участок кода:

Class crntTaskClass=null;
try {
    crntTaskClass=Class.forName(className);
    try {
        Tasks crntTask=(Tasks) crntTaskClass.newInstance();
        crntTask.run();
        System.out.print("\nPress enter to exit: ");
        try {
            new BufferedReader(new InputStreamReader(System.in)).read();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
<p><code>}
catch(ClassNotFoundException e) {
    System.err.println("Solution not found!");
}
in.close();</code></p>
Как видно из примера, блоки try-catch имеют иерархическую структуру. Если честно, то при чтении кода, лично мне он кажется немного неудобным и корявым. Возьмем тот же код и упорядочим вышеуказанные блоки по-другому:
Class crntTaskClass=null;
try {
    crntTaskClass=Class.forName(className);
    Tasks crntTask=(Tasks) crntTaskClass.newInstance();
    crntTask.run();
    System.out.print("\nPress enter to exit: ");
    new BufferedReader(new InputStreamReader(System.in)).read();      
}
catch(ClassNotFoundException e) {
    System.err.println("Solution not found!");
}
catch (IOException e) {
    e.printStackTrace();
}
catch (IllegalAccessException e) {
    e.printStackTrace();
}
catch (InstantiationException e) {
    e.printStackTrace();
} 
in.close();
Вопрос: Если я буду пользоваться вторым стилем оформления блоков try-catch, то не принесет ли это мне некоторые проблемы? Например: сложности поиска "кода-виновника" при отладке или же "перекрытия" ранее объявлеными исключениями всех нижеследующих? Надеюсь на толковый ответ, который мне действительно поможет. Заранее спасибо!
3 ответа

Разбейте всё на методы с семантикой «одна операция с try-catch» и будет вам счастье

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

public void doJob(String className) {
    try {
        runTask(className);
    } catch (ClassNotFoundException e) {
        System.err.println("Solution not found!");
    }
    in.close();
}

private void runTask(final String className) throws ClassNotFoundException {
    final Class crntTaskClass = Class.forName(className);
    try {
        Tasks crntTask = (Tasks) crntTaskClass.newInstance();
        crntTask.run();
        System.out.print("\nPress enter to exit: ");
        readFromReader();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

private void readFromReader() {
    try {
        new BufferedReader(new InputStreamReader(System.in)).read();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Почитайте парочку глав из книжки «Чистый Код» про методы и исключения, всё станет ясно


Неправильная работа с исключениями. Нельзя просто так "глушить" их внутри. Кроме того, при выбросе unchecked исклюения не вызывется in.close(). Лучше так:

public void test() 
    throws 
        ClassNotFoundException, 
        IOException, 
        IllegalAccessException, 
        InstantiationException
{       
    try
    {
        Class crntTaskClass = Class.forName(className);
        Tasks crntTask = (Tasks) crntTaskClass.newInstance();
        crntTask.run();
        System.out.print("\nPress enter to exit: ");
        new BufferedReader(new InputStreamReader(System.in)).read();      
    }
    finally
    {
        in.close();
    }
}

а снаружи что-то вроде:

try
{
    test();
}
catch (Exception e)
{
    logError(e);
}


С точки зрения простоты чтения, лучше разделить нормальный путь выполнения программы и код обработки ошибок. См. "Чистый код" Роберта Мартина. Для этого исключения которые можно передать на верх, передаются наверх.

licensed under cc by-sa 3.0 with attribution.