언어 및 도구들 공부/Java

try-catch와 throw 구문

Dr.Mlem 2024. 9. 27. 21:34

28-Filehelper 의 try-catch 구문

이 코드 안에서, 왜 try-catch 구문으로 감쌌는데 굳이 throw e 로 에러를 밖으로 내보내는거야?


throw e를 사용하여 예외를 다시 던지는 이유는 예외가 발생했음을 호출자에게 알리기 위해서입니다. 이렇게 하면 호출자는 예외를 처리하거나 로그를 남길 수 있습니다. 예외를 다시 던지지 않으면, 예외가 발생했음을 호출자가 알 수 없게 됩니다.

예외를 다시 던지는 것은 예외 처리의 일관성을 유지하고, 호출자에게 예외 상황을 알리는 좋은 방법입니다.


다음은 예외를 다시 던지지 않는 경우와 던지는 경우의 차이를 보여주는 예입니다:

public void write(String filePath, byte[] data) throws Exception {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        // 예외를 다시 던지지 않으면 호출자는 예외가 발생했음을 알 수 없음
    } catch (IOException e) {
        e.printStackTrace();
        // 예외를 다시 던지지 않으면 호출자는 예외가 발생했음을 알 수 없음
    } catch (Exception e) {
        e.printStackTrace();
        // 예외를 다시 던지지 않으면 호출자는 예외가 발생했음을 알 수 없음
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

위 코드에서는 예외가 발생해도 호출자는 이를 알 수 없습니다. 반면에 예외를 다시 던지면 호출자는 예외를 처리할 수 있습니다:

public void write(String filePath, byte[] data) throws Exception {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (IOException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (Exception e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

이렇게 하면 호출자는 예외를 처리하거나 로그를 남길 수 있습니다.



Q2.
왜 throw e가 없으면 호출자는 예외가 나왔는지 알 수 없는거야?


throw e가 없으면 호출자가 예외를 알 수 없는 이유는 예외가 발생했을 때 이를 호출자에게 전달하지 않기 때문입니다. 예외를 다시 던지지 않으면 예외가 발생한 메서드 내에서만 예외가 처리되고, 호출자에게는 예외가 발생했다는 정보가 전달되지 않습니다.

다음은 예외를 다시 던지지 않는 경우와 던지는 경우의 차이를 설명하는 예입니다:

예외를 다시 던지지 않는 경우

public void write(String filePath, byte[] data) {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } catch (IOException e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } catch (Exception e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

위 코드에서는 예외가 발생해도 호출자는 이를 알 수 없습니다. 예외가 발생했음을 로그에 남기지만, 호출자에게는 예외가 발생했다는 정보가 전달되지 않습니다.

예외를 다시 던지는 경우

public void write(String filePath, byte[] data) throws Exception {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (IOException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (Exception e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

이렇게 하면 호출자는 예외를 처리하거나 로그를 남길 수 있습니다. 예외를 다시 던지면 호출자는 예외가 발생했음을 인지하고, 적절한 조치를 취할 수 있습니다. 예를 들어, 호출자는 예외를 잡아서 사용자에게 오류 메시지를 보여주거나, 로그 파일에 예외 정보를 기록할 수 있습니다.


Q3.
try구문에서 에러가 생기면, catch 구문으로 가서 실행을 하고 지나가기 때문에, catch 구문에서 별도의 알림이 없으면 알 수 없기 때문인거야?



네, 맞습니다. try 구문에서 예외가 발생하면 해당 예외를 처리하기 위해 catch 구문으로 이동합니다. catch 구문에서 예외를 처리한 후, 별도의 조치 없이 코드가 종료되면 호출자는 예외가 발생했는지 알 수 없습니다.

예외를 다시 던지지 않으면 호출자는 예외가 발생했음을 인지할 수 없기 때문에, 예외를 다시 던져 호출자에게 예외가 발생했음을 알리는 것이 중요합니다. 이렇게 하면 호출자는 예외를 처리하거나 로그를 남길 수 있습니다.

다음은 예외를 다시 던지지 않는 경우와 던지는 경우의 차이를 설명하는 예입니다:

예외를 다시 던지지 않는 경우

public void write(String filePath, byte[] data) {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } catch (IOException e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } catch (Exception e) {
        e.printStackTrace(); // 예외가 발생했음을 로그에 남기지만 호출자는 알 수 없음
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

위 코드에서는 예외가 발생해도 호출자는 이를 알 수 없습니다. 예외가 발생했음을 로그에 남기지만, 호출자에게는 예외가 발생했다는 정보가 전달되지 않습니다.

예외를 다시 던지는 경우

public void write(String filePath, byte[] data) throws Exception {
    OutputStream os = null;
    try {
        os = new FileOutputStream(filePath);
        os.write(data);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (IOException e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } catch (Exception e) {
        e.printStackTrace();
        throw e; // 예외를 다시 던져 호출자가 처리할 수 있게 함
    } finally {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

이렇게 하면 호출자는 예외를 처리하거나 로그를 남길 수 있습니다. 예외를 다시 던지면 호출자는 예외가 발생했음을 인지하고, 적절한 조치를 취할 수 있습니다. 예를 들어, 호출자는 예외를 잡아서 사용자에게 오류 메시지를 보여주거나, 로그 파일에 예외 정보를 기록할 수 있습니다.