[CS-JAVA] Error & Exception

지영·2023년 8월 23일
0

CS

목록 보기
62/77

Error와 Exception의 차이

프로그램이 실행 중 어떤 원인에 의해서 오작동을 하거나 비정상저으로 종료되는 경우를 프로그램 오류라 하며, 프로그램 오류에는 Error와 Exception이 있다.

Error

컴파일 시 문법적인 오류와 런타임 시 nullpoint 참조와 같은 오류로 프로세스에 심각한 문제를 야기시켜 프로세스를 종료시킬 수 있다. 이와 같이 수습할 수 없는 심각한 문제를 의미한다. 개발자가 미리 예측하거나 방지할 수 없다.

Exception

개발자가 구현한 로직에서 발생한 실수나 사용자의 영향에 의해 발생한다. 해당 예외는 프로그래머가 적절히 코드를 작성해주면 비정상적인 종류를 막을 수 있다. try-catch으로 Exception Handling을 할 수 있다.

Throwable이란

오류와 예외 모두 자바의 최상위 클래스인 Object를 상속받는다. 그리고 그 사이에는 Throwable이란 클래스와 상속관계가 있다. Throwable 클래스의 객체에는 오류나 예외에 대한 메시지를 담는다. 그 외에도 예외가 연결될 때(chained exception) 연결된 예외의 정보들을 기록하기도 한다.

Throwable객체가 가진 정보와 할 수 있는 행위는 getMessage()printStackTrace()라는 메서드로 구현되어 있다. 이를 상속받은 Error와 Exception또한 두 메서드를 사용할 수 있다.

+) 주요 Method
printStackTrace() : 발생한 Exception의 출처를 메모리상에서 추적하면서 결과를 알려줍니다. 발생한 위치를 정확히 출력해줘서 제일 많이 쓰며 void를 반환합니다.
getMessage() : 한줄로 요약된 메세지를 String으로 반환해줍니다.

Error(오류)란

개발자가 미리 대처하기 힘든 것을 말한다. 아래는 오류의 대표적인 예시이다.

  • StackOverflowError : 호출의 깊이가 깊어지거나 재귀가 지속되어 stack overflow 발생 시 던져지는 오류. 이를 피하기 위해서 재귀를 사용할 때 조심하거나, 가시적인 loop를 사용하는 것도 예방법이 될 수 있습니다.

  • OutOfMemoryError : JVM이 할당된 메모리의 부족으로 더 이상 객체를 할당할 수 없을 때, 던져지는 오류. 가비지 컬랙터에 의한 추가적인 메모리 확보가 부족한 상황에 발생하기도 한다. 이를 피하기 위해서는 낭비되는 메모리를 차단하거나, heap의 크기를 늘려주는 방법을 사용할 수도 있다.

Exception(예외)란

  • NullPointerException : 객체가 필요한 경우인데 응용프로그램이 null을 사용하려고 시도할 경우, 던져지는/던질 수 있는 예외입니다.

  • IllegalArgumentException : 메서드가 허가되지 않거나 부적절한 argument를 받았을 경우에 던져지는/던질 수 있는 예외입니다.

🎁 여기서 던질 수 있는이라는 것은 개발자가 임의로 예외를 던질 수 있다는 의미이다.

Exception의 종류

1. Checked Exception

Compile Exception이라고도 한다. Exception을 바로 상속받는다. 컴파일 시점에 예외를 catch하는지를 확인한다. 만약 컴파일 시점에 예외에 대해 처리(try-catch)하지 않는다면 컴파일 에러가 발생한다.
또한 트랜잭션 Rollback이 안된다는 속성도 있다. 예외가 발생하는 메서드에서 throws 예약어로 예외를 호출한 메서드에 전달하는 방법으로 처리가 가능하다.
주로 JVM 외부와 통신(네트워크, 파일시스템 등) 할 때 쓰인다.

  • RuntimeException 이외의 모든 예외
  • IOException, SQLException 등
public class CheckedException {
    public static void main(String[] args) {
        try {
            File file = new File("example.txt");
            Scanner scanner = new Scanner(file);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                System.out.println("line = " + line);
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            System.out.println("An error occurred while reading the file: " + e.getMessage());
        }
    }
}

2. Unchecked Exception

RuntimeException을 상속받는다. 컴파일 시점에 예외를 확인하지 않으므로 컴파일 시점에 예외가 발생하는지 여부를 판단할 수 없다. Checked Exception과 반대로 트랜잭션 Rollback이 된다는 속성도 있다.

예외가 발생하느 메서드에서 throws 예약어를 활용할 필요는 없다 (해도 상관없긴 하다.) 즉, 명시적으로 예외처리를 하지 않아도 된다.

  • RuntimeException 하위의 모든 예외
  • NullPointerException, IndexOutOfBoundExcepion, ArrayIndexOutOfBoundsException 등
public class UncheckedException {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        int index = 10;

        System.out.println("number = " + numbers[index]);
    }
}

에러 발생 이미지

Exception의 사용

  • Checked Exception : 예외에 대한 처리 책임을 확실히 넘길 수 있을 때 사용. 즉 예외가 발생할 수 있는 메소드를 호출하는 메소드가 예외를 활용하여 무엇이가 의미있는 작업을 할 때 유용. 하지만 무분별한 thows의 활용은 코드의 가독성을 떨어뜨리고, 어떤 메서드의 어떤 부분에서 예외가 발생했는지를 알기 어렵게 만드는 원인이 되기도 한다.

  • 아래의 예시는 예외 추적이 쉽도록 리팩토링한 코드이다

출처 : https://toneyparky.tistory.com/40

// bufferedReader.readline()에서 던질 수 있는 IOException을 try-catch로 잡아 UncheckedException으로 바꿔서 던진다.

public static String extractRequestLine(BufferedReader bufferedReader) {
    try {
    	String requestLine = bufferedReader.readLine();
        if (requestLine == null) {
            throw new InvalidHttpRequestException("request line이 없습니다.");
    	}

      return requestLine;
    } catch (IOException e) {
        throw new InvalidHttpRequestException("입력 값이 잘못되어 RequestLine 객체를 생성할 수 없습니다.");
    }
}




*참고 : https://toneyparky.tistory.com/40, https://gyoogle.dev/blog/computer-language/Java/Error%20&%20Exception.html
profile
꾸준함의 힘을 아는 개발자📍

0개의 댓글