исключение «попробуй / поймай против бросков» - PullRequest
113 голосов
/ 14 июля 2010

Эти операторы кода эквивалентны?Есть ли разница между ними?

private void calculateArea() throws Exception {
    ....do something
}

private void calculateArea() {
    try {
        ....do something
    } catch (Exception e) {
        showException(e);
    }
}

Ответы [ 10 ]

138 голосов
/ 14 июля 2010

Да, есть огромная разница - последнее проглатывает исключение (по общему признанию), тогда как первое позволит ему распространяться. (Я предполагаю, что showException не выбрасывает его.)

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

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

19 голосов
/ 14 июля 2010

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

15 голосов
/ 14 июля 2010

Да.Версия, которая объявляет throws Exception, будет требовать, чтобы вызывающий код обрабатывал исключение, тогда как версия, которая явно обрабатывает его, не будет.

, то есть просто:

performCalculation();

vs.перенести бремя обработки исключения на вызывающую сторону:

try {
    performCalculation();
catch (Exception e) {
    // handle exception
}
6 голосов
/ 14 июля 2010

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

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

3 голосов
/ 19 апреля 2014

Существует один конкретный сценарий, когда мы не можем использовать броски, мы должны использовать try-catch. Существует правило «Переопределенный метод не может генерировать никаких дополнительных исключений, кроме того, что генерирует его родительский класс». Если есть какое-либо дополнительное исключение, которое должно быть обработано с помощью try-catch. Рассмотрим этот фрагмент кода. Есть простой базовый класс

package trycatchvsthrows;

public class Base {
    public void show()
    {
        System.out.println("hello from base");
    }
}

и его производный класс:

package trycatchvsthrows;

public class Derived extends Base {

    @Override
    public void show()   {
        // TODO Auto-generated method stub
        super.show();

        Thread thread= new Thread();
        thread.start();
        try {
            thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // thread.sleep(10);
        // here we can not use public void show() throws InterruptedException 
        // not allowed
    }
}

Когда нам нужно вызвать thread.sleep (), мы вынуждены использовать try-catch, здесь мы не можем использовать:

 public void show() throws InterruptedException

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

1 голос
/ 08 августа 2017

Если вы сгенерировали исключение, дочерний метод (который переопределяет это) должен обработать исключение

пример:

class A{
public void myMethod() throws Exception{
 //do something
}
}

A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
1 голос
/ 14 июля 2010

Я предполагаю, что под "идентичным" вы ссылаетесь на поведение.

Поведение функции может быть определено следующим образом:

1) Возвращаемое значение

2)Брошенные исключения

3) Побочные эффекты (то есть изменения в куче, файловой системе и т. Д.)

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

Однако, если вы гарантируете, что «что-то сделать» никогда не вызовет исключение, то поведение будет идентичным (хотя компилятор потребует, чтобы вызывающая сторонаобработать исключение, в первой версии)

- редактировать -

С точки зрения разработки API методы совершенно разные в своем контракте.Кроме того, бросать исключение класса не рекомендуется.Попробуйте добавить что-то более конкретное, чтобы позволить вызывающей стороне лучше обработать исключение.

0 голосов
/ 19 июня 2019
private void calculateArea() throws Exception {
    ....do something
}

Это вызывает исключение, поэтому вызывающая сторона отвечает за обработку этого исключения, но если вызывающая сторона не обрабатывает исключение, возможно, оно будет передано jvm, что может привести к аварийному завершению программы.

В то время как во втором случае:

private void calculateArea() {
    try {
        ....do something
    } catch (Exception e) {
        showException(e);
    }
}

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

Try-catch - рекомендуемый подход.

IMO,

  • Выдает ключевое слово, чаще всего используемое с проверенными исключениями, чтобы убедить компилятор, но он не гарантирует нормальное завершение программы.

  • Выдает ключевое слово, передающее ответственность за обработку исключений
    вызывающая сторона (JVM или другой метод).

  • Ключевое слово throws требуется только для отмеченных исключений, для непроверенных Исключения: здесь не используется ключевое слово throws.

0 голосов
/ 19 января 2017

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

0 голосов
/ 28 ноября 2016

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

private void calculateArea() throws Exception {
    // Do something
}

В примере блока try-catch ниже. Вызывающий этот метод не должен беспокоиться об обработке исключения, поскольку об этом уже позаботились.

private void calculateArea() {
    try {
        // Do something

    } catch (Exception e) {
        showException(e);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...