try / catch 대 예외 발생


117

이 코드 문은 동일합니까? 그들 사이에 차이점이 있습니까?

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

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

3
실제로 답은 아니지만 Ned Batchelder의 Exceptions in the Rainforest 기사에 관심이있을 수 있습니다.이 기사 는 한 스타일 또는 다른 스타일이 선호되는 일반적인 경우를 설명하는 데 도움이됩니다.
Daniel Pryden

1
catch에 "showException (e)"을 사용하는 대신 catch에 "throws e"가 있는지 (또는 try / catch가 전혀 없는지) 물어 보셨습니까?
MacGyver

답변:


146

예, 큰 차이가 있습니다. 후자는 예외를 삼키고 (확실히 보여줍니다) 첫 번째는 전파를 허용합니다. (나는 그것을 다시 showException던지지 않는다고 가정하고 있습니다.)

따라서 첫 번째 메서드를 호출하고 "무언가"가 실패하면 호출자가 예외를 처리해야합니다. 두 번째 메서드를 호출하고 실패 "무언가를"경우를 제외하고 호출자는 일반적으로 나쁜 일이 전혀 예외를 ... 볼 수 없습니다 showException했다 진정으로 잘못 어떤 고정 된 예외를 처리, 일반적으로 확인했다 그 calculateArea목적을 달성했다.

당신은 당신이없이 첫 번째 방법을 호출 할 수 있기 때문에, 이것을 말할 수 있습니다 중 하나를 잡기 Exception자신 또는 귀하의 방법은 너무 그것을 던질 수 있음을 선언.


12
"정말로 예외를 처리하지 않는 한"이라고 언급하면 ​​좋은 점입니다. 나는 단지 "예외"를 잡는 자체가 실제 예외의 지능적인 "처리"로 이어지지 않는다고 덧붙였다. 이것이 사람들이 가능한 가장 구체적인 예외를 잡을 것을 추천하는 이유이다.
Bill K

17
+1. Jon Skeet은 더 많은 평판이 필요하기 때문입니다. 아, 대답도 좋았습니다.
Jonathan Spiller 2013 년

20

첫 번째 throws Exception는 호출자가 Exception. 두 번째는 Exception내부적으로 잡아서 처리 하므로 호출자는 예외 처리를 수행 할 필요가 없습니다.


그래서 간단히 말해서, 나는 항상 두 번째 것을 사용해야합니다. 내가 맞아? 첫 번째는 실제로 프로그램의 다른 지점에서 사용되는 방법입니다. 의 그건 내가 함께 추가 사용에 대한 지침을 gruop하기로 결정하지만 지금은 T가 큰 실수하는 것을 실현하는 것이 .. 수행하는 데 왜
카를로스

9
아니요, 두 패턴이 모두 필요합니다. 메서드가 예외를 처리 할 수있는 경우 두 번째 패턴을 사용하고 그렇지 않은 경우 첫 번째 패턴을 사용하여 호출자에게 알립니다.
Andreas Dolk

사용하는 버전은 요구 사항에 따라 다릅니다. 기본적으로 해당 예외를 처리하는 데 필요한 수준은 무엇입니까? 발신자는 그에 따라 코딩해야합니다. 호출자가 첫 번째 버전을 호출하고 메서드 정의를 두 번째 버전으로 바꾸면 호출자 코드는 확인 된 예외이므로 예외를 처리해야합니다.
samitgaur 2010

16

예. 선언하는 버전 throws Exception은 예외를 처리하기 위해 호출 코드가 필요하지만 명시 적으로 처리하는 버전은 그렇지 않습니다.

즉, 간단히 :

performCalculation();

호출자에게 예외 처리 부담을 이동하는 것과 비교 :

try {
    performCalculation();
catch (Exception e) {
    // handle exception
}

6

예, 그들 사이에는 많은 차이가 있습니다. 첫 번째 코드 블록에서 호출 코드에 예외를 전달합니다. 두 번째 코드 블록에서는 직접 처리합니다. 올바른 방법은 전적으로 수행중인 작업에 따라 다릅니다. 어떤 경우에는 코드에서 예외를 처리하기를 원하지만 (예를 들어 파일을 찾을 수없고 파일을 생성하려는 경우) 다른 경우에는 호출 코드가 예외를 처리하기를 원합니다 (파일을 찾을 수 없음). 그리고 그들은 새로운 것을 지정하거나 만들어야합니다).

일반적으로 말해서 일반적인 예외를 포착하고 싶지 않습니다. 대신 FileNotFoundException또는 같은 특정 항목 만 잡을 IOException수 있습니다. 다른 의미를 가질 수 있기 때문입니다.


3

던지기를 사용할 수없는 특정 시나리오가 하나 있습니다. 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

재정의 된 메서드는 추가 예외를 throw 할 수 없기 때문입니다.


모든 사람이이 경고에 대해 알고있는 것은 아니라고 생각합니다. 잘 지적했다.
ivanleoncz

1

나는 "동일한"당신이 행동을 말하는 것이라고 가정합니다.

함수의 동작은 다음에 의해 결정될 수 있습니다.

1) 반환 값

2) 던져진 예외

3) 부작용 (예 : 힙, 파일 시스템 등의 변경)

이 경우 첫 번째 메서드는 모든 예외를 전파하고 두 번째 메서드는 확인 된 예외를 throw하지 않고 대부분의 확인되지 않은 예외도 삼키므로 동작이 다릅니다.

그러나 "무언가"가 예외를 throw하지 않는다고 보장하면 동작은 동일합니다 (첫 번째 버전에서는 컴파일러가 예외를 처리하도록 호출자가 필요함).

--편집하다--

API 디자인의 관점에서 볼 때 계약 방식은 완전히 다릅니다. 또한 Exception 클래스를 던지는 것은 권장되지 않습니다. 호출자가 예외를 더 잘 처리 할 수 ​​있도록 더 구체적인 것을 던져보십시오.


1

예외가 발생하면 자식 메서드 (이를 재정의)가 예외를 처리해야합니다.

예:

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

A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}

0

호출자가 예외를 처리하기를 원하는 경우가 많습니다. 호출자가 다른 메서드를 호출하는 다른 메서드를 호출하는 메서드를 호출한다고 가정 해 보겠습니다. 각 메서드가 예외를 처리하도록하는 대신 호출자에서 처리 할 수 ​​있습니다. 그 방법이 실패 할 때 방법 중 하나에서 무언가를하고 싶지 않다면.


0

이 메서드의 호출자는이 예외를 포착하거나 메서드 서명에서 다시 발생하도록 선언해야합니다.

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

아래 try-catch 블록 예제에서. 이 메서드의 호출자는 이미 처리되었으므로 예외 처리에 대해 걱정할 필요가 없습니다.

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

    } catch (Exception e) {
        showException(e);
    }
}

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

이렇게하면 예외가 발생하므로 호출자는 해당 예외를 처리 할 책임이 있지만 호출자가 예외를 처리하지 않으면 jvm에 제공되어 프로그램이 비정상적으로 종료 될 수 있습니다.

두 번째 경우 :

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

여기서 예외는 피 호출자가 처리하므로 프로그램이 비정상적으로 종료 될 가능성이 없습니다.

Try-catch 는 권장되는 접근 방식입니다.

IMO,

  • 컴파일러를 설득하기 위해 주로 Checked 예외와 함께 사용되는 키워드를 던지지 만 프로그램의 정상적인 종료를 보장하지는 않습니다.

  • 예외 처리 책임을
    호출자 (JVM 또는 다른 메서드) 에게 위임하는 키워드를 던집니다 .

  • Throws 키워드는 확인 된 예외에만 필요하며, 확인되지 않은 예외의 경우 throws 키워드를 사용하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.