2015-04-19 4 views
1

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

class NegativeException extends RuntimeException { 
} 

class ZeroException extends NegativeException { 
} 

class Driver { 
    static boolean Marathon(int a) { 
     try { 
      if (a < 0) 
       throw new NegativeException(); 
      else if (a == 0) 
       throw new ZeroException(); 
      else if (a >= 42) 
       return true; 
      else 
       return false; 
     } catch (ZeroException e) { 
      System.out.println("Use natural number"); 
     } finally { 
      System.out.println("One last thing"); 
     } 
     System.out.println("All done."); 
     return false; 
    } 

    public static void main(String[] args) { 
     /* One last thing */ 
     /* true */ 
     System.out.println(Marathon(100)); 


     System.out.println(Marathon(0)); 
     System.out.println(Marathon(-5)); 

    } 
} 

То, что я пытаюсь понять, почему не линия «Все сделано» не выполняется при использовании первой линии наш главный метод уволен? Marathon(100)

Кажется, что выполняется оператор finally, и THEN выдается оператор return. Я знаю, что блок finally всегда будет выполняться независимо от того, что произойдет. Однако я не могу понять, как обратные утверждения влияют на поток блоков try catch. Есть ли набор правил, применяемых при попытке возврата из блоков try-cath-finally?

+2

* "класс ZeroException extends NegativeException" * Um .... Помните, что "extends" означает, что есть отношение "есть". «0 является отрицательным», это неверно. –

ответ

4

Что я пытаюсь понять, почему строка «Все сделано» не выполняется при использовании первой строки нашего основного метода? Marathon (100)

Поскольку a >= 42 правда, и так вы делаете:

return true; 

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

Если вы хотите продолжить выполнение, вы бы записать в переменную, а затем один return в конце:

static boolean Marathon(int a) { 
    boolean rv = false; 
    try { 
     if (a < 0) 
      throw new NegativeException(); 
     else if (a == 0) 
      throw new ZeroException(); 
     else if (a >= 42) 
      rv = true; 
    } catch (ZeroException e) { 
     System.out.println("Use natural number"); 
    } finally { 
     System.out.println("One last thing"); 
    } 
    System.out.println("All done."); 
    return rv; 
} 

Подробнее о return в try и catch: Если вы выдаете return изнутри try, который имеет блок finally, он немедленно передает управление блоку finally. Когда конец этого блока достигнут, функция завершается (без с кодом после блок finally, если у вас нет вложенных блоков finally). То же самое происходит, если вы return с точностью до catch.

Так, например:

try { 
    if (someCondition) { 
     return 1; 
    } 
    if (someOtherCondition) { 
     throw new Exception(); 
    } 
} 
catch (Exception e) { 
    System.out.println("Got here because of exception"); 
    return 2; 
} 
finally { 
    System.out.println("Got here"); 
} 
System.out.println("May not have gotten here"); 
return 3; 

"Got here" будет всегда быть выходной, независимо от того, что; это пункт finally статей, они всегда получить выполнен.

"Got here because of exception" будет выводиться только, если someOtherCondition истинно (и будет выводиться перед "Got here"), в этом случае функция возвращает обычно со значением 1.

"May not have gotten here" не будет выводиться, если либо someCondition или someOtherCondition верно, то из-за return с в try и catch блоков.

Если ни одно условие не является истинным, вы видите "May not have gotten here", а затем "Got here", и функция возвращает 3.

Обратите внимание, что return в блоке catch означает, что функция возвращает обычно (со значением 2), когда someOtherCondition верно, то не бросает. Если у вас не было return, а someOtherCondition были истинными, вы бы увидели "Got here because of exception" и "Got here", а затем функция завершилась бы сбрасыванием (без возвращаемого значения) и не выведет "May not have gotten here".

И последнее, но не менее важное: Если у вас есть в finally блоке с return, что return «побеждает»: Даже если вы находитесь в finally блоке, потому что вы уже издало returnreturn, А в конце концов блокируют вытесняет это, заставив функцию вернуть значение finally, а не более раннее.

+1

@JBNizet: Вправо: * «... он завершает функцию в этой точке (запрет« finally »clauses и т. Д.)« Означает «кроме« окончательных »предложений и таких» - например, они ** будут ** получить исполнение. Я передумаю, возможно, «запрет» не ясен для всех. –

+0

@ T.J.Crowder Отлично! Это просто прояснило все это! Спасибо! – Dimitri

+1

@Dimitri: Рад, что помогло. Я сложил этот материал в ответ. :-) –

Смежные вопросы