programing

Java 예외가 검출되지 않았습니까?

luckcodes 2022. 8. 15. 11:17

Java 예외가 검출되지 않았습니까?

트라이캐치 구성에 대해 이론적으로 작은 문제가 있습니다.

어제 Java에 관한 실기 시험을 봤는데, 다음 예를 이해할 수 없습니다.

try {
    try {
        System.out.print("A");
        throw new Exception("1");
    } catch (Exception e) {
        System.out.print("B");
        throw new Exception("2");
    } finally {
        System.out.print("C");
        throw new Exception("3");
    }
} catch (Exception e) {
    System.out.print(e.getMessage());
}

문제는 "출력은 어떻게 보일까?"였습니다.

AB2C3일 줄 알았는데, 정말 놀랍네요. 사실이 아니에요.

정답은 ABC3입니다(테스트가 완료되어 실제로 그렇게 되어 있습니다.

질문입니다. 예외('2')는 어디로 갔습니까?

Java Language Specification 14.20.2에서 다음을 수행합니다.

이유 R에 의해 캐치 블록이 갑자기 종료되면 최종적으로 블록이 실행된다.그리고 선택할 수 있습니다.

  • 최종적으로 블록이 정상적으로 완료되면 이유 R에 의해 try 문이 갑자기 완료됩니다.

  • 이유 S로 인해 최종적으로 블록이 갑자기 완료된 경우 이유 S(및 이유 R이 폐기됨) 인해 try 문이 갑자기 완료됩니다.

따라서 예외를 발생시키는 캐치블록이 있는 경우:

try {
    // ...
} catch (Exception e) {
    throw new Exception("2");
}

단, 예외를 발생시키는 최종 블록도 있습니다.

} finally {
    throw new Exception("3");
}

Exception("2")되고 '''만 남습니다.Exception("3")파됩니니다다

마지막으로 블록에 입력된 예외가 시행 블록 또는 캐치 블록에서 이전에 입력된 예외를 억제합니다.

Java 7의 예:http://ideone.com/0YdeZo

Javadoc의 예에서:


static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

단, 이 예에서는 메서드가 readLine을 사용하여 양쪽 슬로우 예외를 닫으면 readFirstLineFromFileWithFinallyBlock 메서드가 마지막 블록에서 슬로우된 예외를 슬로우합니다.트라이 블록에서 슬로우된 예외는 억제됩니다.


★★★★★try-withJava 7 구문에는 예외 억제의 다른 단계가 추가되어 있습니다. parttry block에서 에 던져진 합니다.

예를 들어 다음과 같습니다.

try (
        java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
        for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {
            String newLine = System.getProperty("line.separator");
            String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
        }
    }

리소스 포함 시도 문과 관련된 코드 블록에서 예외를 발생시킬 수 있습니다.위의 예에서는 ZipFile 및 BufferedWriter 개체를 닫으려고 할 때 try-with-resources 문에서 예외를 슬로우할 수 있습니다.try 블록에서 예외가 느려지고 try-with-resources 문에서1개 이상의 예외가 느려지면 try-with-resources 문에서 느려지는 예외가 억제되고 writeToFileZipFileContents 메서드에 의해 느려지는 예외가 됩니다.이러한 억제된 예외를 취득하려면 try block에 의해 느려진 예외에서 Throwable.getSuppressed 메서드를 호출합니다.


질문에서 나온 코드에서는 각 블록이 오래된 예외를 완전히 폐기하고 로깅도 하지 않습니다.몇 가지 버그를 해결하려고 하면 문제가 생깁니다.

http://en.wikipedia.org/wiki/Error_hiding

부터throw new Exception("2");에서 던져졌다catch막아서지 않고try다시 잡히지 않습니다.
14.20.2를 참조해 주세요. try-finallytry-catch-finally 실행.

다음과 같은 일이 발생합니다.

try {
    try {
        System.out.print("A");         //Prints A
        throw new Exception("1");   
    } catch (Exception e) { 
        System.out.print("B");         //Caught from inner try, prints B
        throw new Exception("2");   
    } finally {
        System.out.print("C");         //Prints C (finally is always executed)
        throw new Exception("3");  
    }
} catch (Exception e) {
    System.out.print(e.getMessage());  //Prints 3 since see (very detailed) link
}

당신의 질문은 매우 명확하고, 답은 매우 간단합니다.메시지가 "2"인 Exception 객체는 "3"인 Exception 객체에 의해 덮어씁니다.

설명 : 예외 발생 시 처리할 블록을 잡기 위해 던진 개체입니다.그러나 캐치 블록 자체에서 예외가 발생하면 해당 객체는 예외 처리를 위해 OUTER CATCH 블록(있는 경우)으로 전송됩니다.그리고 여기도 같은 일이 일어났다.메시지 "2"가 포함된 예외 개체가 OUTER catch 블록으로 전송됩니다. 하지만 기다려 주십시오.내부 트라이캐치 블록을 떠나기 전에 최종적으로 실행해야 합니다.여기 우리가 우려하는 변화가 발생했습니다.새 예외 개체(메시지 "3" 포함)가 삭제되거나 마지막으로 이미 던져진 예외 개체(메시지 "2")를 대체한 블록이 생성됩니다.그 결과 Exception 객체의 메시지가 출력되면 "2"가 아닌 "3"과 같은 오버라이드 값이 표시됩니다.

Keep Remember : CATCH 블록에서 처리할 수 있는 예외 오브젝트는 1개뿐입니다.

finally블록은 항상 실행됩니다.너나return테스트 블록 내부에서 전송되지 않으면 예외가 느려집니다.에 입력된 예외는finally블록은 캐치브런치에 던져진 블록보다 우선됩니다.

또한 예외를 발생시켜도 출력 자체는 발생하지 않습니다.회선throw new Exception("2");아무것도 쓰지 않습니다.

고객님의 코드에 따라:

try {
    try {
        System.out.print("A");
        throw new Exception("1");   // 1
    } catch (Exception e) {
        System.out.print("B");      // 2
        throw new Exception("2");
    } finally {                     // 3
        System.out.print("C");      // 4 
        throw new Exception("3");
    }
} catch (Exception e) {             // 5
    System.out.print(e.getMessage());
}

여기 보시는 바와 같이

  1. A를 인쇄하여 예외를 발생시키다# 1;
  2. 이 예외는 catch 스테이트먼트와 인쇄에 의해 포착되었습니다.B - # 2;
  3. 마침내 저지하다# 3try-pair(또는 예외가 발생하지 않은 경우 try-pair) 스테이트먼트 후에 실행되어 인쇄됩니다.C - # 4새로운 예외를 던졌습니다.
  4. 이것은 외부 어획 문구에 의해 포착되었다.# 5;

결과는ABC3.그리고.2와 같은 방법으로 생략된다.1

언급URL : https://stackoverflow.com/questions/18097496/java-exception-not-caught