Try, Catch, Finally

KKH_94·2023년 6월 9일
0

JAVA

목록 보기
25/36

try-catch-finally는 자바에서 예외 처리를 위한 구문입니다.

이 구문은 예외가 발생할 수 있는 코드 블록을 지정하고, 예외가 발생했을 때 예외를 처리하는 코드를 작성하며, 예외 발생 여부와 관계없이 항상 실행되어야 하는 코드를 정의하는 데 사용됩니다.

try-catch-finally 구문 형식은 다음과 같습니다

try {
    // 예외가 발생할 수 있는 코드
} catch (예외 타입1 변수1) {
    // 예외 처리 코드
} catch (예외 타입2 변수2) {
    // 예외 처리 코드
} finally {
    // 항상 실행되어야 하는 코드
}

try 블록: 예외가 발생할 수 있는 코드를 포함합니다. 이 블록 안에서 예외가 발생하면 해당 예외를 처리할 catch 블록으로 이동합니다.

catch 블록: 예외를 처리하는 코드를 작성하는 블록입니다. catch 블록은 예외 타입과 해당 예외를 참조할 변수를 지정하여 어떤 종류의 예외를 처리할지 정의합니다. 여러 개의 catch 블록을 사용하여 다양한 종류의 예외를 처리할 수 있습니다. 예외가 발생한 경우, 해당 예외와 일치하는 첫 번째 catch 블록으로 이동하여 예외 처리 코드를 실행합니다.

finally 블록: 예외 발생 여부와 관계없이 항상 실행되어야 하는 코드를 작성하는 블록입니다. finally 블록은 선택적으로 사용할 수 있으며, try-catch 구문의 마지막 부분에 위치합니다.

아래는 try-catch-finally 구문을 사용한 예제 코드입니다

public class TryCatchFinallyExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Caught ArithmeticException: " + e.getMessage());
        } finally {
            System.out.println("Finally block executed");
        }
    }

    public static int divide(int dividend, int divisor) {
        return dividend / divisor;
    }
}

위의 예제에서 divide() 메서드에서는 0으로 나누는 연산을 수행하고 있습니다.

이 연산은 ArithmeticException을 발생시킵니다. try 블록에서는 이 코드를 실행하고, 예외가 발생하면 catch 블록으로 이동하여 해당 예외를 처리합니다.

마지막으로 finally 블록은 항상 실행되는 코드를 포함하고 있습니다.

다양한 try catch finally 예제들

1. 파일 입출력에서의 예외 처리

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileExample {
    public static void main(String[] args) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("example.txt"));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("Error reading the file: " + e.getMessage());
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                System.out.println("Error closing the file: " + e.getMessage());
            }
        }
    }
}

위의 예제에서는 파일을 읽어오는 동안 발생할 수 있는 IOException을 처리하는 예제입니다.

파일을 열고 읽는 동안 예외가 발생하면 catch 블록으로 이동하여 예외를 처리하고, finally 블록에서는 파일을 닫는 작업을 수행합니다.

2. 네트워크 통신에서의 예외 처리

import java.io.IOException;
import java.net.Socket;

public class NetworkExample {
    public static void main(String[] args) {
        Socket socket = null;
        try {
            socket = new Socket("example.com", 8080);
            // 네트워크 통신 수행
        } catch (IOException e) {
            System.out.println("Error connecting to the server: " + e.getMessage());
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.out.println("Error closing the socket: " + e.getMessage());
                }
            }
        }
    }
}

위의 예제에서는 네트워크 통신 시 발생할 수 있는 IOException을 처리하는 예제입니다. 서버에 연결하는 동안 예외가 발생하면 catch 블록에서 예외를 처리하고, finally 블록에서는 소켓을 닫는 작업을 수행합니다.

3. 데이터베이스 연결에서의 예외 처리

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseExample {
    public static void main(String[] args) {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");
            // 데이터베이스 작업 수행
        } catch (SQLException e) {
            System.out.println("Error connecting to the database: " + e.getMessage());
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    System.out.println("Error closing the database connection: " + e.getMessage());
                }
            }
        }
    }
}

위의 예제는 데이터베이스 연결 시 발생할 수 있는 SQLException을 처리하는 예제입니다. 데이터베이스에 연결하는 동안 예외가 발생하면 catch 블록에서 예외를 처리하고, finally 블록에서는 데이터베이스 연결을 닫는 작업을 수행합니다.

4. 배열 인덱스 예외 처리

public class ArrayExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        try {
            for (int i = 0; i <= numbers.length; i++) {
                System.out.println(numbers[i]);
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Array index out of bounds: " + e.getMessage());
        } finally {
            System.out.println("Finally block executed");
        }
    }
}

위의 예제에서는 배열의 범위를 벗어나는 인덱스에 접근하는 예외를 처리하는 예제입니다. 예외가 발생하면 catch 블록에서 예외를 처리하고, finally 블록은 항상 실행됩니다.

5. 숫자 변환 예외 처리

public class NumberExample {
    public static void main(String[] args) {
        String number = "abc";
        try {
            int value = Integer.parseInt(number);
            System.out.println("Parsed value: " + value);
        } catch (NumberFormatException e) {
            System.out.println("Error parsing the number: " + e.getMessage());
        } finally {
            System.out.println("Finally block executed");
        }
    }
}

위의 예제는 숫자로 변환할 수 없는 문자열을 숫자로 변환하려고 할 때 발생하는 NumberFormatException을 처리하는 예제입니다. 예외가 발생하면 catch 블록에서 예외를 처리하고, finally 블록은 항상 실행됩니다.

6. 외부 리소스 해제

import java.io.FileInputStream;
import java.io.IOException;

public class ResourceExample {
    public static void main(String[] args) {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("file.txt");
            // 파일에서 데이터를 읽어옴
        } catch (IOException e) {
            System.out.println("Error reading the file: " + e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    System.out.println("Error closing the file: " + e.getMessage());
                }
            }
        }
    }
}

위의 예제에서는 파일을 읽어오는 동안 발생할 수 있는 IOException을 처리하고, 파일을 닫는 작업을 finally 블록에서 수행합니다. try-catch-finally 구문을 사용하여 예외 처리와 리소스의 해제를 보장합니다.

7. 사용자 정의 예외 처리 (Static Class)

class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class CustomExceptionExample {
    public static void main(String[] args) {
        try {
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (CustomException e) {
            System.out.println("Caught CustomException: " + e.getMessage());
        } finally {
            System.out.println("Finally block executed");
        }
    }

    public static int divide(int dividend, int divisor) throws CustomException {
        if (divisor == 0) {
            throw new CustomException("Divisor cannot be zero");
        }
        return dividend / divisor;
    }
}

위의 예제에서는 사용자 정의 예외인 CustomException을 정의하고, 해당 예외가 발생할 경우 예외를 처리하는 예제입니다. divide() 메서드에서는 0으로 나누는 연산 시 CustomException을 발생시키고, catch 블록에서 해당 예외를 처리합니다.

8. 다중 예외 처리

public class MultipleExceptionExample {
    public static void main(String[] args) {
        try {
            String str = null;
            int length = str.length();
            int result = divide(10, 0);
            System.out.println("Result: " + result);
        } catch (NullPointerException | ArithmeticException e) {
        
        	if (e instanceof NullPointerException) { 
            //instanceof : e 가 NullPointerException의 객체인지 아닌지 확인.
                System.out.println("Caught NullPointerException: " + e.getMessage());
            } else if (e instanceof ArithmeticException) {
                System.out.println("Caught ArithmeticException: " + e.getMessage());
            } else {
                System.out.println("Caught exception: " + e.getMessage());
            }
            
        } finally {
            System.out.println("Finally block executed");
        }
    }

    public static int divide(int dividend, int divisor) {
        return dividend / divisor;
    }
}

위의 예제에서는 NullPointerExceptionArithmeticException을 동시에 처리하는 다중 예외 처리를 보여줍니다. try 블록에서 NullPointerException이 발생하면 해당 예외를 처리하고, 이어서 ArithmeticException이 발생하면 같은 catch 블록에서 처리합니다.

9. 예외 전파

public class ExceptionPropagationExample {
    public static void main(String[] args) {
        try {
            someMethod();
        } catch (Exception e) {
            System.out.println("Caught exception: " + e.getMessage());
        } finally {
            System.out.println("Finally block executed");
        }
    }

    public static void someMethod() throws Exception {
        anotherMethod();
    }

    public static void anotherMethod() throws Exception {
        throw new Exception("Exception thrown from anotherMethod");
    }
}

위의 예제에서는 예외를 다른 메서드로 전파하는 예제입니다. anotherMethod()에서 발생한 예외가 someMethod()로 전파되고, 이어서 main() 메서드에서 처리됩니다.

10. printStackTrace() 메서드 예제

public class PrintStackTraceExample {
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Caught ArithmeticException: " + e.getMessage());
e.printStackTrace();
} finally {
System.out.println("Finally block executed");
}
}

public static int divide(int dividend, int divisor) {
    return dividend / divisor;
}

}
위의 예제에서는 ArithmeticException이 발생할 때 catch 블록에서 해당 예외를 처리하고, e.getMessage()를 통해 예외 메시지를 출력합니다. 그리고 e.printStackTrace()를 호출하여 예외의 스택 트레이스를 콘솔에 출력합니다.

11. getMessage() 메서드 예제

public class GetMessageExample {
public static void main(String[] args) {
try {
String str = null;
int length = str.length();
System.out.println("String length: " + length);
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e.getMessage());
} finally {
System.out.println("Finally block executed");
}
}
}

위의 예제에서는 NullPointerException이 발생할 때 catch 블록에서 해당 예외를 처리하고, e.getMessage()를 통해 예외 메시지를 출력합니다.

이러한 예제들은 printStackTrace() 메서드를 사용하여 예외의 스택 트레이스를 출력하고, getMessage() 메서드를 사용하여 예외의 메시지를 출력하는 방법을 보여줍니다. 이를 통해 예외에 대한 정보를 얻거나 디버깅에 도움을 줄 수 있습니다.

이러한 예제들은 try-catch-finally 구문을 활용하여 예외 상황에 대한 명확한 처리와 정리 작업을 수행하는 방법을 보여줍니다. 예외가 발생한 후 catch 블록이 실행되고, 이어서 finally 블록이 실행된 것을 확인할 수 있습니다.

이처럼 try-catch-finally 구문은 예외 처리와 관련된 코드를 작성할 때 유용하게 사용됩니다. catch 블록은 예외를 처리하고, finally 블록은 항상 실행되어야 하는 정리 작업 등을 수행할 때 사용됩니다.


Throw

Throw는 자바에서 예외를 명시적으로 발생시키는 키워드입니다. 예외가 발생한 상황을 나타내고, 해당 예외를 호출자에게 전달하는 역할을 합니다. Throw를 사용하여 예외를 발생시키면 프로그램의 흐름이 중단되고 예외 처리 메커니즘이 시작됩니다.

Throw의 기본 구문은 다음과 같습니다:

throw <예외 객체>;

<예외 객체>: 발생시킬 예외를 나타내는 객체입니다. 주로 Exception 클래스 또는 그 하위 클래스의 객체를 사용합니다. 개발자가 직접 예외 객체를 생성하여 사용할 수도 있습니다.
Throw 키워드를 사용하여 예외를 발생시키면, 예외 객체는 호출 스택을 따라 위로 전파됩니다. 예외를 처리할 수 있는 catch 블록이 없는 경우, 예외는 호출 스택을 거슬러 올라가며 처리를 찾습니다. 이러한 과정에서 예외가 처리되지 않으면 프로그램은 비정상적으로 종료됩니다.

Throw는 주로 다음과 같은 상황에서 사용됩니다:

예외 조건이 발생했을 때 해당 예외를 명시적으로 발생시키고자 할 때.

특정 상황에서 프로그램을 중지시키고 예외 처리 메커니즘을 트리거할 때.

사용자 정의 예외를 생성하고 발생시킬 때.

Throw를 사용하여 예외를 발생시킴으로써 예외 상황을 알리고, 이에 대한 적절한 처리를 수행할 수 있습니다. 예외 처리는 프로그램의 안정성과 신뢰성을 높이는 데 중요한 역할을 합니다.


Exception 클래스 객체를 throw하는 코드

public class ThrowExample {
    public static void main(String[] args) {
        try {
            throwException();
        } catch (Exception e) {
            System.out.println("Caught exception: " + e.getMessage());
        }
    }

    public static void throwException() throws Exception {
        throw new Exception("Custom exception message");
    }
}

위의 코드에서는 throwException() 메서드에서 Exception 객체를 직접 생성하여 throw 키워드를 사용하여 예외를 발생시킵니다. throwException() 메서드에서는 throws Exception을 선언하여 해당 메서드에서는 예외를 처리하지 않고, 호출한 곳으로 예외를 전파합니다.

다음은 Throw 문을 사용한 다양한 자바 코드 예제입니다.

1. 예외 던지기

public class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class Example {
    public static void main(String[] args) {
        try {
            throw new CustomException("예외 발생!");
        } catch (CustomException e) {
            System.out.println(e.getMessage());
        }
    }
}

2. Null 값 확인 예외 던지기

public class Example {
    public static void printLength(String str) throws NullPointerException {
        if (str == null) {
            throw new NullPointerException("문자열이 null입니다.");
        } else {
            System.out.println("문자열의 길이: " + str.length());
        }
    }

    public static void main(String[] args) {
        try {
            String text = null;
            printLength(text);
        } catch (NullPointerException e) {
            System.out.println(e.getMessage());
        }
    }
}

3. ArithmeticException 발생 시키기

public class Example {
    public static void divide(int dividend, int divisor) {
        if (divisor == 0) {
            throw new ArithmeticException("0으로 나눌 수 없습니다.");
        } else {
            int result = dividend / divisor;
            System.out.println("나눈 결과: " + result);
        }
    }

    public static void main(String[] args) {
        try {
            divide(10, 0);
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }
}

4. 배열 인덱스 예외 던지기

public class Example {
    public static void accessArray(int[] arr, int index) {
        if (index < 0 || index >= arr.length) {
            throw new ArrayIndexOutOfBoundsException("유효하지 않은 배열 인덱스입니다.");
        } else {
            System.out.println("배열 요소: " + arr[index]);
        }
    }

    public static void main(String[] args) {
        try {
            int[] numbers = {1, 2, 3};
            accessArray(numbers, 5);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(e.getMessage());
        }
    }
}

5. 파일 입출력 예외 던지기

import java.io.*;

public class Example {
    public static void readFile(String filePath) throws IOException {
        File file = new File(filePath);
        BufferedReader reader = null;
        
        try {
            reader = new BufferedReader(new FileReader(file));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    public static void main(String[] args) {
        try {
            String filePath = "example.txt";
            readFile(filePath);
        } catch (IOException e) {
            System.out.println("파일을 읽는 중에 오류가 발생했습니다.");
            e.printStackTrace();
        }
    }
}

6. 사용자 정의 예외 던지기

public class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

public class Example {
    public static void checkValue(int value) throws CustomException {
        if (value < 0) {
            throw new CustomException("유효하지 않은 값입니다.");
        } else {
            System.out.println("값: " + value);
        }
    }

    public static void main(String[] args) {
        try {
            int number = -5;
            checkValue(number);
        } catch (CustomException e) {
            System.out.println(e.getMessage());
        }
    }
}

이러한 예제들은 Throw 문을 사용하여 예외를 명시적으로 발생시키는 방법을 보여줍니다. 이를 통해 예외 상황을 처리하고, 코드의 안정성을 높일 수 있습니다.

Throw을 사용할 때 주의해야 할 몇 가지 사항이 있습니다

  1. 예외의 적절한 선택 : 예외는 예상 가능하고 복구 가능한 상황에서 발생해야 합니다. 따라서 예외를 발생시킬 때에는 예외의 의미와 상황에 적합한 예외 클래스를 선택해야 합니다. 자바에서는 다양한 예외 클래스를 제공하므로 적절한 예외 클래스를 선택하는 것이 중요합니다.

  2. 예외 처리 메커니즘 활용 : 예외를 발생시킨다면, 그 예외를 적절하게 처리할 수 있는 예외 처리 메커니즘을 구현해야 합니다. try-catch 블록을 사용하여 예외를 처리하거나, 호출자에게 예외를 전파하여 처리하도록 할 수 있습니다. 예외 발생 후에는 프로그램의 정상적인 흐름을 유지하기 위해 적절한 예외 처리를 해주어야 합니다.

  3. 과용하지 않기 : 예외는 예외적인 상황에서 발생해야 하므로, 예외를 너무 많이 사용하거나 모든 상황에 대해 예외를 발생시키는 것은 좋지 않습니다. 일반적인 흐름 제어나 오류 처리는 예외보다 다른 방식으로 처리하는 것이 바람직합니다. 예외는 예외 상황에만 사용되어야 합니다.

  4. 성능에 주의 : 예외 처리는 추가적인 비용이 발생할 수 있으므로, 성능에 영향을 줄 수 있습니다. 예외를 발생시키는 작업은 상대적으로 비용이 크므로, 성능에 민감한 부분에서 너무 자주 예외를 발생시키는 것은 피해야 합니다.

  5. 예외의 적절한 문서화 : 예외를 발생시킬 때 해당 예외에 대한 문서화를 제공해야 합니다. 예외의 발생 조건, 예외 메시지, 호출자가 예외를 처리해야 하는 방법 등을 문서화하여 개발자에게 명확하게 전달해야 합니다.

예외 처리는 프로그램의 신뢰성과 안정성을 높이는 데 중요한 역할을 합니다. 따라서 예외를 발생시킬 때는 신중하게 고려하고 적절한 예외 처리를 수행해야 합니다.

각각의 주의사항에 해당하는 예제 코드

  1. 예외의 적절한 선택:

public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}

public class ExceptionSelectionExample {
public static void main(String[] args) {
try {
throw new CustomException("Custom exception occurred");
} catch (CustomException e) {
System.out.println("Caught CustomException: " + e.getMessage());
}
}
}

위의 코드에서는 CustomException 클래스를 사용하여 예외를 발생시킵니다. 이 예제에서는 예외의 의미와 상황에 맞는 예외 클래스를 선택하는 예시입니다.

  1. 예외 처리 메커니즘 활용:

public class ExceptionHandlingExample {
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Caught ArithmeticException: " + e.getMessage());
}
}

public static int divide(int dividend, int divisor) {
    try {
        return dividend / divisor;
    } catch (ArithmeticException e) {
        throw e;
    }
}

}

위의 코드에서는 divide() 메서드에서 ArithmeticException이 발생하면 예외를 다시 throw하여 호출자에게 전파합니다. 이 예제에서는 예외 처리 메커니즘을 활용하여 예외를 전파하는 방식을 보여줍니다.

  1. 과용하지 않기:

public class AvoidExceptionOveruseExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i <= numbers.length; i++) {
try {
System.out.println(numbers[i]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage());
}
}
}
}

위의 코드에서는 배열의 범위를 벗어나는 인덱스에 접근하는 예외를 처리합니다. 이 예제에서는 예외를 피하기 위해 배열의 범위를 체크하여 예외 발생을 방지하는 방식을 보여줍니다.

  1. 성능에 주의:

public class PerformanceConsiderationExample {
public static void main(String[] args) {
try {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
process(i);
}
} catch (OutOfMemoryError e) {
System.out.println("Caught OutOfMemoryError: " + e.getMessage());
}
}

public static void process(int value) {
    // 예외적인 상황이 아니라면 예외를 발생시키지 않음
    if (value % 1000 == 0) {
        throw new OutOfMemoryError("Out of memory");
    }
}

}

위의 코드에서는 예외를 피하기 위해 process() 메서드에서 예외를 발생시키지 않는 경우

를 처리합니다. 이 예제에서는 성능에 영향을 줄 수 있는 예외 발생을 피하는 방식을 보여줍니다.

  1. 예외의 적절한 문서화:

public class ExceptionDocumentationExample {
public static void main(String[] args) {
try {
process(null);
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e.getMessage());
}
}

public static void process(String str) {
    if (str == null) {
        throw new NullPointerException("String cannot be null");
    }
}

}

Throws
throws는 메서드 선언부에서 해당 메서드에서 발생할 수 있는 예외를 명시하는 키워드입니다. throws를 사용하여 예외를 선언하면, 메서드 호출자에게 해당 예외를 처리하도록 요구할 수 있습니다. 이를 통해 예외 처리의 책임을 메서드 호출자에게 위임할 수 있습니다.

throws의 기본 구문은 다음과 같습니다:

[접근 제어자] 반환타입 메서드명([매개변수]) throws 예외클래스1, 예외클래스2, ... {
// 메서드 내용
}
예외클래스1, 예외클래스2, ...: 해당 메서드에서 발생할 수 있는 예외 클래스들을 나열합니다. 각 예외 클래스는 쉼표로 구분됩니다.
throws를 사용하여 예외를 선언하면, 메서드에서 발생하는 예외를 호출자에게 알리고, 호출자가 해당 예외를 처리하도록 할 수 있습니다. 호출자는 선언된 예외를 try-catch 블록으로 처리하거나, 자신을 호출한 메서드로 예외를 전파할 수 있습니다.

throws는 주로 다음과 같은 상황에서 사용됩니다:

  1. 예외를 처리할 책임이 호출자에게 있을 때: 메서드가 예외를 처리할 수 있는 능력이 부족하거나, 메서드 외부에서 예외를 처리할 필요가 있는 경우 throws를 사용하여 예외 처리를 호출자에게 위임할 수 있습니다. 이렇게 함으로써 예외 처리의 책임을 분산시킬 수 있습니다.

  2. 예외가 발생할 수 있는 경우를 명시할 때: 메서드가 예외를 발생시킬 수 있는 경우, throws를 사용하여 호출자에게 해당 예외의 발생 가능성을 알려줄 수 있습니다. 이는 명시적인 예외 처리를 유도하고, 코드의 가독성과 안정성을 높이는 데 도움이 됩니다.

  3. 체크된 예외를 처리할 필요가 있는 경우: 체크된 예외는 컴파일러가 예외 처리를 강제하는 예외로, throws를 사용하여 호출자에게 예외 처리를 요구할 수 있습니다. 이는 컴파일러에 의한 예외 처리 검사를 통해 예외를 처리하는 코드를 보다 안전하게 구현할 수 있도록 합니다.

  4. 예외 처리의 표준화를 위해: 여러 메서드에서 동일한 예외를 처리해야 할 경우, 예외를 throws로 선언하여 예외 처리를 통일할 수 있습니다. 이는 코드의 일관성과 유지 보수성을 향상시키는 데 도움이 됩니다.

throws는 예외 처리를 유연하게 구현할 수 있는 도구이지만, 과용될 경우 코드의 가독성이 저하되거나 예외 처리의 복잡성이 증가할 수 있습니다. 따라서 throws를 사용할 때는 신중하게 예외 처리의 적절성을 판단하고, 코드의 일관성과 가독성을 유지하는 데 주의해야 합니다.

아래는 throws를 사용하는 예제 코드입니다:

public class ThrowsExample {
public static void main(String[] args) {
try {
process();
} catch (CustomException e) {
System.out.println("Caught CustomException: " + e.getMessage());
}
}

public static void process() throws CustomException {
    // 예외 발생 조건
    if (/* 예외 조건 */) {
        throw new CustomException("Custom exception occurred");
    }

    // 예외가 발생하지 않은 경우 정상적으로 처리
}

}

class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
위의 코드에서 process() 메서드는 throws CustomException을 선언하여 CustomException 예외를 처리하지 않고 호출자로 전파합니다. main() 메서드에서는 process() 메서드를 호출하고, catch 블록에서 CustomException을 처리합니다.

  1. 여러 예외를 동시에 처리하기 위한 throws 구문:

import java.io.*;

public class MultipleExceptionsExample {
public static void main(String[] args) {
try {
process();
} catch (FileNotFoundException | IOException e) {
System.out.println("Caught Exception: " + e.getMessage());
}
}

public static void process() throws FileNotFoundException, IOException {
    FileInputStream file = new FileInputStream("file.txt");
    // 파일에서 데이터 읽어오는 작업
    file.close();
}

}
위의 코드에서 process() 메서드에서 throws FileNotFoundException, IOException을 선언하여 파일 처리 중 발생할 수 있는 두 가지 예외를 호출자로 전파합니다. main() 메서드에서는 이를 동시에 처리하기 위해 catch 블록에 FileNotFoundException | IOException을 사용합니다.

  1. 상속 관계에 있는 예외를 처리하기 위한 throws 구문:

import java.rmi.RemoteException;
import java.rmi.NotBoundException;

public class RemoteExceptionExample {
public static void main(String[] args) {
try {
connectToServer();
} catch (RemoteException e) {
System.out.println("Caught RemoteException: " + e.getMessage());
} catch (NotBoundException e) {
System.out.println("Caught NotBoundException: " + e.getMessage());
}
}

public static void connectToServer() throws RemoteException, NotBoundException {
    // 서버에 연결하는 작업
}

}
위의 코드에서 connectToServer() 메서드에서 throws RemoteException, NotBoundException을 선언하여 RMI(Remote Method Invocation) 관련 예외를 호출자로 전파합니다. main() 메서드에서는 각각의 예외를 처리하기 위해 별도의 catch 블록을 사용합니다.

  1. 사용자 정의 예외를 throws로 전파하기:

class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}

public class CustomExceptionExample {
public static void main(String[] args) {
try {
throwCustomException();
} catch (CustomException e) {
System.out.println("Caught CustomException: " + e.getMessage());
}
}

public static void throwCustomException() throws CustomException {
    throw new CustomException("Custom exception occurred");
}

}
위의 코드에서 throwCustomException() 메서드에서 throws CustomException을 선언하여 사용자 정의 예외인 CustomException을 호출자로 전파합니다. main() 메서드에서는 이 예외를 처리하기 위해 catch 블록을 사용합니다.

  1. throws를 사용하여 예외를 다시 던지기 (Exception Re-Throwing):

import java.io.IOException;

public class RethrowExceptionExample {
public static void main(String[] args) {
try {
processFile("file.txt");
} catch (IOException e) {
System.out.println("Caught IOException: " + e.getMessage());
}
}

public static void processFile(String fileName) throws IOException {
    try {
        // 파일을 열고 데이터 처리 작업
    } catch (IOException e) {
        // 예외를 처리하지 않고 다시 던짐
        throw e;
    }
}

}

위의 코드에서 processFile() 메서드에서는 파일을 처리하다가 IOException이 발생하면 예외를 다시 던집니다. main() 메서드에서는 이 예외를 처리하기 위해 catch 블록을 사용합니다.

각 예제는 throws를 사용하여 예외를 선언하고, 호출자에게 예외 처리를 요구하는 방식을 보여줍니다. 이를 통해 예외 처리를 더욱 유연하게 구현할 수 있습니다.

profile
_serendipity

0개의 댓글