2024.09.02.월.TIL 예외처리

김기남·2024년 9월 2일
post-thumbnail

안녕하세요, 오늘은 예외처리에 대한 내용을 정리해보았습니다.

Error와 Exception

Java에서는 Compile 오류, Runtime 오류 두 종류가 있다.
Compile 오류는 IDE에서도 미리 알 수 있기 때문에 잡아내기 쉽지만,
Runtime은 해결하기 까다롭다. Java에서 Runtime 오류는 Error와 Exception이 있다.

  • Exception, Error의 계층구조

  • Throwable
    - getMessage(), printStackTrace()와 같은 메서드가 구현되어 있다.
    - Exception, Error에 대한 Message를 기록한다.
    - Chain 된 예외들의 정보를 기록합니다.
    - 공식문서 설명 참고
    https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html

  • Error
    - 코드로 복구되지 않는 오류

    • 개발자가 직접 Error를 catch하면 안된다. 해결할 수 없다.
      - ex) OOM(OutOfMemory Error) - 실행중 메모리 부족
  • Exception
    - 개발자가 직접 처리할 수 있는 오류
    - ex) NPE(NullPointerException), IllegalArgumentException
    - Compile Exception
    - Checked Exception 이다.
    - Compiler 가 확인한다.
    - Runtime Exception
    - Unchecked Exception 이다.
    - Compile 후 실행(Runtime)단계에 발생하는 Exception
    - Compile, Runtime

  • Exception 상속관계

    	- 상속 개념은 Exception에도 적용된다.
    	- catch 를 통해 예외를 잡으면 하위 Exception들도 모두 catch 한다.
    	- Throwable Class를 catch 하면 안된다. Error Class도 모두 catch되기 때문
    	- 즉, Exception 하위 클래스만 예외 처리를 하면 된다.

catch, throws

Application의 정상 동작흐름

예외 처리를 하는 방법

  • try, catch, finally, throws, throw
  1. catch
  • 예외가 발생하면 처리한다.
  • Exception 상속관계에 의해, 하위 Exception이 모두 catch 된다.
    • 따라서 Exception을 catch 하는건 지양해야 한다.
      • 어떤 Exception이 발생했는지 모르기 때문
      • 모든 Exception이 해당 catch로 처리되기 때문
  1. finally
  • 예외 발생 여부를 떠나서 최종적으로 실행될 코드
try {
	// 예외가 발생할 코드
} catch (Exception) {
  // 예외 발생하면 처리하는 코드
} finally {

	// 예외를 발생하던, 안하던 최종적으로 실행될 코드 
	
}
  1. throw
  • 예외를 발생시키는 코드
  • 예외 또한 객체이기 때문에 new 키워드를 사용하여 사용할 수 있다.
// 1.
	throw new TestCheckedException("내가 만든 메세지");

// 2.
try {

} catch (Exception) {
	throw new TestCheckedException("내가 만든 메세지");
}
  1. throws

  • 예외가 발생하면 던진다.
  • Exception 상속관계에 의해, 하위 Exception이 모두 throw 된다.
  • Java의 main 메서드를 넘어서 throw 하게되면 로그를 출력하며 종료된다.
    • 즉, 그 이전에 꼭 catch 해서 처리해야 한다.

Checked Exception, Unchecked Exception

Checked Exception

  • Exception class를 상속받으면 checked Exception이 된다.
  • Compiler가 체크한다.
  • Checked Exception은 발생한 예외를 개발자가 명시적으로 처리해야 한다.
    • catch 혹은 throws 로 처리한다.
      • throws 했다면 이후에 꼭 catch 해야한다.
    • 만약, 처리하지 않으면 Compile 오류가 발생한다.
// Exception class를 상속받아 만든 Custom Exception
// Exception Class를 상속받으면 checked Exception이 된다.
public class TestCheckedException extends Exception {

	public TestCheckedException(String message) {
		super(message);
	}
	
}

// throw new 로 Exception을 발생시키는 메서드 + throws로 넘긴다.
public class ThrowException {

	public void throwException() throws TestCheckedException {
		throw new TestCheckedException("내가 만든 메세지");
	}
	
}

// catch 하는 메서드, throws 하는 메서드
public class CatchException {

	ThrowException throw = new ThrowException();
	
	// 1. catch 하는 메서드
	public void catchException() {
		
		try {
			// 예외 발생되는 메서드
			throw.throwException();
			
		} catch (TestCheckedException e) {
			System.out.println(e.getMessage());
		}
		
		// 이후 코드가 있으면 정상적으로 실행됨.
		
	}
	
	// 2. throws 하는 메서드
	public void throwsException() throws TestCheckedException {
		
		// 예외 발생되는 메서드
		throw.throwException();
	
	}

}

// 1. catch 하는 경우 - 정상동작 후 종료
public class Main {
	
	public static void main(String[] args) {
		
		CatchException test = new CatchException();
		
		// 1. catch 메서드 호출
		test.catchException();
		
		System.out.println("마지막 코드 실행");

	}
	
}

// 2. throws 하는 경우 - Message를 출력하여 프로그램 종료
public class Main {
	
	public static void main(String[] args) throws TestCheckedException {
		
		CatchException test = new CatchException();

		// 2. throws 메서드 호출
		test.throwsException();
		
		System.out.println("마지막 코드 실행");
	}
	
}
  • 예외는 개발자가 미리 알고 대처가 가능한 예외가 좋다.
    • 단, checked 예외는 꼭 처리(catch, throws)가 필요하기 때문에 너무.. 번거롭다…

Unchecked Exception

  • RuntimeException과 하위 Exception
  • 말그대로 Compiler가 체크하지 않는다.
  • Unchecked Exception은 발생한 예외를 개발자가 명시적으로 처리하지 않아도 된다.
  • throws를 생략할 수 있다. Checked Exception은 꼭 처리 해야됨
// RuntimeException class를 상속받아 만든 Custom Exception
// RuntimeException Class를 상속받으면 Unchecked Exception이 된다.
public class TestUncheckedException extends RuntimeException {

	public TestUncheckedException(String message) {
		super(message);
	}
	
}


// throw new 로 Exception을 발생시키는 메서드 + throws 생략.
public class ThrowException {

	// throws 생략가능, 알아서 던진다.
	public void throwException() {
		throw new TestUncheckedException("내가 만든 메세지2");
	}
	
}


// catch, throws 하지 않으면 알아서 throws 한다.
public class CatchException {

	ThrowException throw = new ThrowException();
	
	// 1. catch 처리가능 된다.
	public void catchException() {
		
		try {
			// 예외 발생되는 메서드
			throw.throwException();
			
		} catch (TestUncheckedException e) {
			System.out.println(e.getMessage());
		}
		
		// 이후 코드가 있으면 정상적으로 실행됨.
		
	}
	
	// 2. catch 하지 않으면 throws 된다.
	public void throwException() {
	
		throw.throwException();
		
	}

}


// 1. catch 하는 경우 - 정상동작 후 종료
public class Main {
	
	public static void main(String[] args) {
		
		CatchException test = new CatchException();
		
		// 1. catch 메서드 호출
		test.catchException();
		
		System.out.println("마지막 코드 실행");

	}
	
}


// 2. throws 하는 경우 - Message를 출력하여 프로그램 종료
public class Main {
	
	public static void main(String[] args) throws TestCheckedException {
		
		CatchException test = new CatchException();

		// 2. throws 메서드 호출
		test.throwsException();
		
		System.out.println("마지막 코드 실행");
	}
	
}
  • throws 생략 가능
    • throws를 명시하여도 compile 시 checked 되진 않는다.
    • 다른 개발자가 인지할 수 있도록 명시하는것도 좋은 방법. 기본은 생략이다.
      • 코드 컨벤션 중 하나
  • 개발자가 실수로 예외 처리를 까먹을 수 있다. Compiler가 check 하지 않기 때문.

정리

  • Checked Exception
    • throws, catch 를 생략할 수 없다.
  • Unchecked Exception
    • throws, catch 를 생략할 수 있다.

코드카타

등차수열, 등비수열이 주어질 때, 다음 원소 값 알아내기

class Solution {

    public int solution(int[] common) {
        int answer = 0;

        if (common[1] - common[0] == common[2] - common[1]) {
            answer = common[common.length - 1] + (common[1] - common[0]);
        } else {
            answer = common[common.length - 1] * (common[1] / common[0]);
        }

        return answer;
    }
}
profile
새로운 시작~!

0개의 댓글