sourcecode

Java에서 선택된 예외와 선택되지 않은 예외 이해

copyscript 2022. 8. 15. 21:30
반응형

Java에서 선택된 예외와 선택되지 않은 예외 이해

"Effective Java"의 Jooshua Bloch는 다음과 같이 말했다.

복구 가능한 상태에 대해서는 체크된 예외를 사용하고 프로그래밍 오류에 대해서는 런타임 예외를 사용합니다(2판 항목 58).

내가 이걸 제대로 이해했는지 보자.

체크된 예외에 대한 이해는 다음과 같습니다.

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}

1. 상기 사항은 체크된 예외로 간주됩니까?

2. 실행 시선택되지 않은 예외?

체크되지 않은 예외에 대한 저의 이해는 다음과 같습니다.

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}

4. 위의 코드도 체크 예외가 될 수 없습니까? 이렇게 복구해도 될까요? 해도 될까요? (주의: 제 세 번째 질문은catch위)

try{
    String filePath = //read in from user input file path
    File file = new File(filePath);
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){
    //Kindly prompt the user an error message
    //Somehow ask the user to re-enter the file path.
}

5. 사람들은 왜 이런 짓을 할까?

public void someMethod throws Exception{

}

왜 그들은 예외를 부풀려 놓았을까?오류를 빨리 처리하는 게 낫지 않나요?왜 거품이 일어나요?

6. 정확한 예외를 표시해야 합니까, 아니면 예외를 사용하여 숨겨야 합니까?

이하가 제 판독치입니다.

Java에서는 언제 체크된 예외를 만들어야 하며 런타임 예외로 해야 합니까?

선택 및 선택되지 않은 예외를 선택해야 하는 경우

많은 사람들은 체크된 예외(즉, 명시적으로 잡거나 다시 던져야 하는 예외)는 전혀 사용하지 말아야 한다고 말합니다.예를 들어 C#에서는 삭제되어 대부분의 언어에는 없습니다.그래서 당신은 항상 서브클래스를 던질 수 있습니다.RuntimeException(예외)

단, 체크된 예외는 편리하다고 생각합니다.이는 API 사용자에게 예외적인 상황을 어떻게 처리해야 할지 생각하도록 강요하고 싶을 때 사용합니다(복구 가능한 경우).체크된 예외는 Java 플랫폼에서 너무 많이 사용되기 때문에 사람들이 이를 싫어할 뿐입니다.

이 주제에 대한 저의 확장된 견해입니다.

구체적인 질문에 대해서:

  1. 이요?NumberFormatException선택된 예외를 고려하시겠습니까?
    아니요.NumberFormatException선택 해제됨(=은 의 하위 클래스임)RuntimeException왜? 나도 몰라 (하지만 다른 방법이 있었어야 했는데)isValidInteger(..))

  2. RuntimeException체크되지 않은 예외?
    그래요, 바로 그 건물이에요.

  3. 여기서 뭘 해야 하죠?
    이 코드가 어디에 있고 원하는 것이 무엇이냐에 따라 다릅니다.UI 계층에 있는 경우 탐지하여 경고를 표시합니다. 서비스 계층에 있는 경우 탐지하지 말고 버블 상태로 둡니다.예외를 받아들이지 마세요.대부분의 경우 예외가 발생할 경우 다음 중 하나를 선택해야 합니다.

    • 기록했다가 돌아오다
    • 다시 던지다(메서드로 던지다)
    • 현재의 예외를 컨스트럭터로 전달함으로써 새로운 예외를 작성한다.
  4. 위의 코드도 체크 예외가 될 수 있지 않을까요?이렇게 복구해도 될까요?내가 할 수 있을까?
    그럴 수도 있었어.하지만 체크되지 않은 예외를 잡는 것도 막을 수 없습니다.

  5. 왜 사람들은 클래스를 추가하는가?Exception스로우즈 조항에서요?
    가장 많은 이유는 사람들이 무엇을 잡고 무엇을 다시 던질지 고민하는 것을 게을리하기 때문입니다.던지다Exception나쁜 관행이므로 피해야 합니다.

유감스럽게도 언제 잡을지, 언제 다시 던질지, 언제 체크 표시를 사용할지, 그리고 언제 체크 표시를 하지 않은 예외를 사용할지를 결정할 수 있는 규칙은 없습니다.나는 이것이 많은 혼란과 많은 나쁜 코드를 야기한다는 것에 동의한다.일반적인 원리는 Bloch에 의해 명시되어 있습니다(당신이 그 일부를 인용했습니다.일반적인 원칙은 처리할 수 있는 레이어에 예외를 재투입하는 것입니다.

어떤 것이 "체크된 예외"인지 여부는 당신이 그것을 잡았는지 또는 당신이 캐치블록에서 무엇을 했는지는 관계가 없습니다.예외 클래스의 속성입니다.의 서브클래스에 속하는 모든 것Exception 제외하고RuntimeException그 서브클래스는 체크된 예외입니다.

Java 컴파일러는 체크된 예외를 캐치하거나 메서드시그니처에 선언하도록 강제합니다.프로그램의 안전성을 향상시키기로 되어 있었지만, 설계상의 문제를 일으킬 만한 가치가 없다는 것이 중론인 것 같습니다.

왜 그들은 예외를 부풀려 놓았을까?오류는 빠르면 빠를수록 좋지 않나요?왜 거품이 일어나요?

그게 예외의 전부니까요이 가능성이 없으면 예외가 필요하지 않습니다.이러한 기능을 사용하면 오류가 처음 발생하는 낮은 수준의 방법으로 오류를 처리하지 않고 사용자가 선택한 수준에서 오류를 처리할 수 있습니다.

  1. 상기 사항은 체크된 예외로 간주됩니까?아니요 예외를 처리한다고 해서 예외가 되는 것은 아닙니다.Checked Exception의 경우RuntimeException.

  2. RuntimeException한 사람unchecked exception? 네

Checked Exceptions이다subclassesjava.lang.Exception Unchecked Exceptions이다subclassesjava.lang.RuntimeException

체크된 예외를 송신하는 콜은 try{}블록으로 둘러싸거나 메서드 호출자의 위 레벨로 처리해야 합니다.이 경우, 현재의 메서드는, 발신자가 예외를 처리하기 위한 적절한 준비를 실시할 수 있도록, 전술한 예외를 슬로우 하는 것을 선언할 필요가 있습니다.

이게 도움이 됐으면 좋겠다.

Q: 정확한 예외를 표시해야 합니까, 아니면 예외를 사용하여 숨겨야 합니까?

A: 네, 이것은 매우 좋은 질문이며 설계상의 중요한 고려 사항입니다.클래스 예외는 매우 일반적인 예외 클래스로 내부 로우 레벨 예외를 래핑하는 데 사용할 수 있습니다.커스텀 예외를 생성하여 그 안에 랩하는 것이 좋습니다.하지만, 그리고 큰 문제는 근본적인 근본 원인을 결코 모호하게 하지 않는다는 것입니다.ex의 경우Don't ever다음 작업을 수행합니다.

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.
}

대신 다음 작업을 수행합니다.

try {
     attemptLogin(userCredentials);
} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.
}

본래의 근본 원인을 없애는 것은 실제 원인을 회복할 수 없는 것으로, 애플리케이션 로그와 에러 메시지 밖에 액세스 할 수 없는 실가동 서포트 팀에게 있어서 악몽입니다.비록 후자가 더 나은 디자인이지만, 개발자들이 기본적인 메시지를 발신자에게 전달하는 데 실패하기 때문에 많은 사람들이 그것을 자주 사용하지 않는다.그러니 확실하게 메모해 두세요.Always pass on the actual exception응용 프로그램 고유의 예외로 래핑되었는지 여부를 확인합니다.

트라이캐치 시RuntimeExceptions

RuntimeException는 일반적으로 트라이캐치하지 마십시오.이들은 일반적으로 프로그래밍 오류를 나타내므로 그대로 두어야 합니다.대신 프로그래머는 에러 상태를 체크한 후 어떤 코드를 호출해야 합니다.RuntimeException. ex의 경우:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welcome to my site!);
} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

이것은 잘못된 프로그래밍 관행입니다.대신 null-check는 다음과 같이 수행되어야 합니다.

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);
} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");
}

단, 번호 포맷 등 에러 체크에 비용이 많이 드는 경우가 있습니다.이 점을 고려해 주십시오.

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));
} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");
}

여기서 호출 전 오류 체크는 기본적으로 parseInt() 메서드 내의 모든 문자열에서 정수 변환 코드를 복제하는 것을 의미하며 개발자에 의해 구현될 경우 오류가 발생하기 쉽기 때문에 수행할 필요가 없습니다.그래서 그냥 트라이캐치를 없애는 것이 더 낫다.

그렇게NullPointerException그리고.NumberFormatException둘 다이다RuntimeExceptions캐치, 캐치업NullPointerExceptiongraceful null-check로 대체해야 합니다.단, 이 체크박스를 사용하는 것을 추천합니다.NumberFormatException에러 발생 가능성이 있는 코드의 도입을 회피하기 위해서입니다.

1. 예외가 불분명한 경우 API를 확인합니다.

 java.lang.Object
 extended by java.lang.Throwable
  extended by java.lang.Exception
   extended by java.lang.RuntimeException  //<-NumberFormatException is a RuntimeException  
    extended by java.lang.IllegalArgumentException
     extended by java.lang.NumberFormatException

2. 네, 그리고 그 범위를 확장하는 모든 예외 사항입니다.

3. 같은 예외를 잡아서 던질 필요는 없습니다.이 경우 새 파일 대화상자를 표시할 수 있습니다.

4. FileNotFoundException은 이미 체크된 예외입니다.

5. 메서드 호출이 예상되는 경우someMethod예외를 잡기 위해 후자를 던질 수 있습니다.그냥 패스하는 거야.사용 방법의 예로는, 독자적인 프라이빗 메서드로 송신해, 대신에 퍼블릭 메서드로 예외를 처리하는 경우를 들 수 있습니다.

Oracle 문서 자체는 http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html에서 읽을 수 있습니다.

설계자는 왜 검출되지 않은 체크되지 않은 모든 예외를 자신의 범위 내에서 지정할 수 있도록 방법을 강제하기로 결정했습니까?메서드에 의해 느려질 수 있는 예외는 메서드의 퍼블릭프로그래밍 인터페이스의 일부입니다.메서드를 호출하는 사용자는 메서드에 대해 수행할 작업을 결정할 수 있도록 메서드가 발생 가능한 예외를 알고 있어야 합니다.이러한 예외는 매개 변수 및 반환 값만큼 메서드의 프로그래밍 인터페이스의 일부입니다.

다음 질문은 다음과 같습니다. "메서드의 API를 문서화하는 것이 매우 좋다면 런타임 예외도 지정하는 것이 어떻습니까?"런타임 예외는 프로그래밍 문제로 인한 문제를 나타내므로 API 클라이언트코드가 이들로부터 회복되거나 어떤 방식으로든 처리될 것으로 합리적으로 기대할 수 없습니다.이러한 문제에는 0으로 나누는 것과 같은 산술 예외, Null 참조를 통해 개체에 액세스하려는 것과 같은 포인터 예외, 너무 크거나 너무 작은 인덱스를 통해 배열 요소에 액세스하려는 것과 같은 인덱싱 예외가 포함됩니다.

Java Language Specification에는 다음과 같은 중요한 정보도 포함되어 있습니다.

throws 절에서 명명된 체크된 예외 클래스는 메서드 또는 컨스트럭터의 구현자와 사용자 간의 계약의 일부입니다.

결론은 IMHO는 어떤 것이든 잡을 수 있다는 것이다.RuntimeException단, 체크되지 않은 예외는 계약의 일부가 아니기 때문에 구현이 필요하지 않습니다.실제로 구현은 체크되지 않은 예외를 유지할 필요가 없습니다.

1) 아니요, 번호Format Exception은 선택되지 않은 예외입니다.체크가 해제되어 있기 때문에 (필수가 아닌) 검출이 되어 있는 경우라도.이것은, 의 서브 클래스이기 때문입니다.IllegalArgumentException의 서브클래스입니다.RuntimeException.

2)RuntimeException체크되지 않은 모든 예외의 루트입니다.의 모든 서브클래스RuntimeException체크되어 있지 않습니다.기타 모든 예외 및Throwable에러를 제외하고 체크됩니다(아래에 있습니다).Throwable).

3/4) 존재하지 않는 파일을 선택했음을 사용자에게 경고하고 새 파일을 요구할 수 있습니다.또는 잘못된 정보를 입력했음을 사용자에게 알리지 않습니다.

5) 던지고 잡기'Exception'나쁜 관행입니다.다만, 보다 일반적으로, 발신자가 대처 방법을 결정할 수 있도록, 다른 예외를 설정할 수 있습니다.예를 들어 일부 파일 입력을 처리하기 위해 라이브러리를 작성하고 메서드에 존재하지 않는 파일이 전달된 경우 이 문제를 어떻게 처리해야 할지 알 수 없습니다.발신자가 다시 묻기를 원합니까, 아니면 종료하시겠습니까?따라서 예외는 체인을 통해 발신자에게 돌아갑니다.

많은 경우,unchecked Exception프로그래머가 입력을 검증하지 않았기 때문에 발생합니다(의 경우).NumberFormatException첫 번째 질문에서)를 참조해 주세요.그렇기 때문에 이러한 예외를 발생시키지 않는 보다 우아한 방법이 있기 때문에 이들을 잡는 것은 선택 사항입니다.

체크 표시 - 발생하기 쉽다.컴파일 시간을 확인.

예: 파일 조작

[UnChecked](체크되지 않음) - 잘못된 데이터가 원인입니다.Run time(실행시간) 체크인을 했다.

예..

String s = "abc";
Object o = s;
Integer i = (Integer) o;

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at Sample.main(Sample.java:9)

여기서의 예외는 불량 데이터로 인해 발생하며 컴파일 시간 중에는 확인할 수 없습니다.

런타임 예외 : 런타임 예외는 선택되지 않은 예외로 참조됩니다.다른 모든 예외는 체크된 예외이며 java.lang에서 파생되지 않습니다.Runtime Exception 입니다.

체크된 예외 : 체크된 예외는 코드 내 어딘가에서 검출되어야 합니다.체크된 예외를 발생시키는 메서드를 호출해도 체크된 예외를 잡지 못하면 코드가 컴파일되지 않습니다.그래서 체크 예외라고 불리는 것입니다.컴파일러는 처리 또는 선언이 되었는지 확인합니다.

Java API의 많은 메서드가 체크된 예외를 슬로우하기 때문에 작성하지 않은 메서드에 의해 생성된 예외에 대처하기 위해 예외 핸들러를 작성하는 경우가 많습니다.

체크된 예외는 컴파일 시 JVM 및 리소스(files/db/stream/socket 등)에 의해 체크됩니다.체크된 예외의 동기는 리소스를 사용할 수 없는 경우 응용 프로그램이 이를 catch/finally block으로 처리하는 대체 동작을 정의해야 한다는 것입니다.

선택되지 않은 예외는 순전히 프로그램 오류, 잘못된 계산, null 데이터 또는 심지어 비즈니스 로직 장애로 인해 런타임 예외가 발생할 수 있습니다.체크되지 않은 예외를 코드로 처리/캐치하는 것은 전혀 문제가 없습니다.

http://coder2design.com/java-interview-questions/에서 인용한 설명

마지막 질문에 대답하려면(다른 질문들은 모두 위에 답변한 것처럼 보입니다), "정확한 예외를 표시해야 합니까, 아니면 예외를 사용하여 숨겨야 합니까?"

이런 걸 말하는 거겠죠?

public void myMethod() throws Exception {
    // ... something that throws FileNotFoundException ...
}

아니요, 항상 가장 정확한 예외 또는 해당 목록을 선언합니다.메서드를 던질 수 있다고 선언하는 예외는 메서드와 발신자 간의 계약의 일부입니다.던지다"FileNotFoundException"는, 파일명이 무효가 되어 파일을 찾을 수 없는 경우가 있는 것을 의미합니다.발신자는 그것을 인텔리전트하게 처리할 필요가 있습니다.던지다Exception"야, 이런 일은 일어나지 않아."알겠습니다." 아주 가난한 일이지만API.

첫 번째 기사의 코멘트에는 "throws"가 몇 가지 예시되어 있습니다.Exception"는 타당하고 합리적인 선언이지만 대부분의 경우 그렇지 않습니다.normal영원히 쓸 수 있는 코드.

체크된 예외는 외부 라이브러리를 사용하는 개발자에게 예외적인 상황에서 해당 라이브러리의 코드가 잘못될 수 있다는 것을 상기시키는 좋은 방법이라고 생각합니다.

체크되지 않은 예외와 체크되지 않은 예외의 차이에 대한 제가 가장 좋아하는 설명은 Java Tutorial trail 기사 "Unchecked Exceptions - the Devestion"에서 확인할 수 있습니다(이 게시물에 모든 초급자를 등록하게 되어 죄송하지만 기본이 가장 좋은 경우도 있습니다).

요점은 다음과 같습니다.클라이언트가 예외로부터 회복될 것으로 합리적으로 예상할 수 있는 경우는, 체크 마크가 붙은 예외로 합니다.클라이언트가 예외에서 복구하기 위해 아무것도 수행할 수 없는 경우 선택되지 않은 예외로 만듭니다.

"어떤 유형의 예외를 던질 것인가"의 핵심은 의미론(어느 정도)이며, 위의 인용문은 훌륭한 가이드라인을 제공합니다(따라서 저는 C#이 체크된 예외를 제거했다는 개념, 특히 Liskov가 그 유용성에 대해 주장하듯이) 아직도 놀라움을 금치 못하고 있습니다.

나머지는 논리적으로 됩니다.컴파일러는 어떤 예외에 대해 명시적으로 응답하기를 기대합니까?클라이언트가 회복될 것으로 예상되는 것.

왜 그들은 예외를 부풀려 놓았을까?오류를 빨리 처리하는 게 낫지 않나요?왜 거품이 일어나요?

예를 들어 클라이언트 서버 어플리케이션과 클라이언트가 검출할 수 없는 자원을 요구했다고 칩시다.또, 유저 요구를 처리하는 동안, 서버측에서 발생한 에러도 있습니다.그러면, 클라이언트에 대해서, 요구했던 것을 취득할 수 없었던 이유를 통지하는 것이 서버의 의무입니다.서버측에서 예외는 삼키거나 처리하지 않고 throw 키워드를 사용하여 슬로우하도록 코드가 작성됩니다.서버가 처리하거나 삭제하면 클라이언트에 어떤 오류가 발생했는지 알릴 수 없습니다.

주의: 발생한 오류 유형을 명확하게 설명하기 위해 자체 Exception 개체를 생성하여 클라이언트에 전달합니다.

체크된 예외를 전혀 사용하지 않는 이유를 추가하고 싶을 뿐입니다.이것은 완전한 답변은 아니지만, 당신의 질문의 일부에 대한 답변이 되고 다른 많은 답변에 대한 보완이 될 것으로 생각합니다.

체크된 예외가 관련될 때마다throws CheckedException메서드 시그니처의 어딘가에 있습니다(CheckedException체크 마크가 붙어 있는 예외일 수 있습니다).시그니처는 예외를 발생시키지 않습니다.예외를 발생시키는 것은 구현의 한 측면입니다.인터페이스, 메서드시그니처, 부모 클래스 등 모든 것이 구현에 의존해서는 안 됩니다.여기서 체크된 예외의 사용방법(실제로 다음 사항을 선언해야 함)throwsmethod signature)는, 이러한 인터페이스의 실장에 의해서, 보다 높은 레벨의 인터페이스를 바인드 합니다.

예를 들어 보겠습니다.

이렇게 깔끔한 인터페이스를 만들어 봅시다.

public interface IFoo {
    public void foo();
}

이제 우리는 많은 방법의 구현을 쓸 수 있다.foo(), 다음과 같이

public class Foo implements IFoo {
    @Override
    public void foo() {
        System.out.println("I don't throw and exception");
    }
}

반 푸는 완벽하게 괜찮아.자, 이제 바 수업에서 첫 번째 시도를 해보겠습니다.

public class Bar implements IFoo {
    @Override
    public void foo() {
        //I'm using InterruptedExcepton because you probably heard about it somewhere. It's a checked exception. Any checked exception will work the same.
        throw new InterruptedException();
    }
}

이 클래스 막대가 컴파일되지 않습니다.중단된 대로예외는 선택된 예외입니다. 예외는 캡처(foo() 메서드 내에서 트라이캐치)하거나 던지겠다고 선언해야 합니다(추가).throws InterruptedException to the method signature). As I don't want to capture this exception here (I want it to propagate upwards so I can properly deal with it somewhere else), let's alter the signature.

public class Bar implements IFoo {
    @Override
    public void foo() throws InterruptedException {
        throw new InterruptedException();
    }
}

This class Bar won't compile either! Bar's method foo() does NOT override IFoo's method foo() since their signatures are different. I could remove the @Override annotation, but I want to program against interface IFoo like IFoo foo; and later on decide on which implementation I want to use, like foo = new Bar();. If Bar's method foo() doesn't override IFoo's method foo, when I do foo.foo(); it won't call Bar's implementation of foo().

To make Bar's public void foo() throws InterruptedException override IFoo's public void foo() I MUST add throws InterruptedException to IFoo's method signature. This, however, will cause problems with my Foo class, since it's foo() method's signature differs from IFoo's method signature. Furthermore, if I added throws InterruptedException to Foo's method foo() I would get another error stating that Foo's method foo() declares that it throws an InterruptedException yet it never throws an InterruptedException.

As you can see (if I did a decent job at explaining this stuff), the fact that I'm throwing a checked exception like InterruptedException is forcing me to tie my interface IFoo to one of it's implementations, which in turn causes havoc on IFoo's other implementations!

This is one big reason why checked exceptions are BAD. In caps.

One solution is to capture the checked exception, wrap it in an unchecked exception and throw the unchecked exception.

  • Java distinguishes between two categories of exceptions (checked & unchecked).
  • Java enforces a catch or declared requirement for checked exceptions.
  • An exception's type determines whether an exception is checked or unchecked.
  • All exception types that are direct or indirect subclasses of class RuntimeException are unchecked exception.
  • All classes that inherit from class Exception but not RuntimeException are considered to be checked exceptions.
  • Classes that inherit from class Error are considered to be unchecked.
  • Compiler checks each method call and deceleration to determine whether the method throws checked exception.
    • If so the compiler ensures the exception is caught or is declared in a throws clause.
  • To satisfy the declare part of the catch-or-declare requirement, the method that generates the exception must provide a throws clause containing the checked-exception.
  • Exception classes are defined to be checked when they are considered important enough to catch or declare.

Here is a simple rule that can help you decide. It is related to how interfaces are used in Java.

Take your class and imagine designing an interface for it such that the interface describes the functionality of the class but none of the underlying implementation (as an interface should). Pretend perhaps that you might implement the class in another way.

Look at the methods of the interface and consider the exceptions they might throw:

If an exception can be thrown by a method, regardless of the underlying implementation (in other words, it describes the functionality only) then it should probably be a checked exception in the interface.

If an exception is caused by the underlying implementation, it should not be in the interface. Therefore, it must either be an unchecked exception in your class (since unchecked exceptions need not appear in the interface signature), or you must wrap it and rethrow as a checked exception that is part of the interface method.

To decide if you should wrap and rethrow, you should again consider whether it makes sense for a user of the interface to have to handle the exception condition immediately, or the exception is so general that there is nothing you can do about it and it should propagate up the stack. Does the wrapped exception make sense when expressed as functionality of the new interface you are defining or is it just a carrier for a bag of possible error conditions that could also happen to other methods? If the former, it might still be a checked exception, otherwise it should be unchecked.

You should not usually plan to "bubble-up" exceptions (catch and rethrow). Either an exception should be handled by the caller (in which case it is checked) or it should go all the way up to a high level handler (in which case it is easiest if it is unchecked).

Just to point out that if you throw a checked exception in a code and the catch is few levels above, you need to declare the exception in the signature of each method between you and the catch. So, encapsulation is broken because all functions in the path of throw must know about details of that exception.

In short, exceptions which your module or modules above are supposed to handle during runtime are called checked exceptions; others are unchecked exceptions which are either RuntimeException or Error.

In this video, it explains checked and unchecked exceptions in Java:
https://www.youtube.com/watch?v=ue2pOqLaArw

All of those are checked exceptions. Unchecked exceptions are subclasses of RuntimeException. The decision is not how to handle them, it's should your code throw them. If you don't want the compiler telling you that you haven't handled an exception then you use an unchecked (subclass of RuntimeException) exception. Those should be saved for situations that you can't recover from, like out of memory errors and the like.

Checked Exceptions :

  • The exceptions which are checked by the compiler for smooth execution of the program at runtime are called Checked Exception.

  • These occur at compile time.

  • If these are not handled properly, they will give compile time error (Not Exception).
  • All subclasses of Exception class except RuntimeException are Checked Exception.

    Hypothetical Example - Suppose you are leaving your house for the exam, but if you check whether you took your Hall Ticket at home(compile time) then there won't be any problem at Exam Hall(runtime).

Unchecked Exception :

  • The exceptions which are not checked by the compiler are called Unchecked Exceptions.

  • These occur at runtime.

  • If these exceptions are not handled properly, they don’t give compile time error. But the program will be terminated prematurely at runtime.

  • All subclasses of RunTimeException and Error are unchecked exceptions.

    Hypothetical Example - Suppose you are in your exam hall but somehow your school had a fire accident (means at runtime) where you can't do anything at that time but precautions can be made before (compile time).

If anybody cares for yet another proof to dislike checked exceptions, see the first few paragraphs of the popular JSON library:

"Although this is a checked exception, it is rarely recoverable. Most callers should simply wrap this exception in an unchecked exception and rethrow: "

So why in the world would anyone make developers keep checking the exception, if we should "simply wrap it" instead? lol

http://developer.android.com/reference/org/json/JSONException.html

All exceptions must be checked exceptions.

  1. Unchecked exceptions are unrestricted gotos. And unrestricted gotos are considered a bad thing.

  2. Unchecked exceptions break encapsulation. To process them correctly, all the functions in the call tree between the thrower and the catcher must be known to avoid bugs.

  3. Exceptions are errors in the function that throws them but not errors in the function that processes them. The purpose of exceptions is to give the program a second chance by deferring the decision of whether it's an error or not to another context. It's only in the other context can the correct decision be made.

ReferenceURL : https://stackoverflow.com/questions/6115896/understanding-checked-vs-unchecked-exceptions-in-java

반응형