자바 study(jdeep) 발표 - exception

12170 단어 studystudy

checked , unchecked exception

에러 ( 시스템에 비정상적인 상황 발생)

  • OutOfMemoryError, ThreadDeath

출처: https://madplay.github.io/post/java-checked-unchecked-exceptions

checked Exception
주로 외부의영향으로 발생하는것들이며, 프로그램사용자들의 동작에 의해서 발생하는경우가 많다.
컴파일시점에 확인할수있는 예외
(FileNotFoundException , ClassNotFoundExcption, DataFormatException 등)
컴파일시점에 확인되어, 바로 예외처리해줘야한다.

Unchecked Exception
일반적으로 발생을 예측할수없고 복구할수없는 예외를 뜻함. 주로 외부API사용, programming errors 등으로 나타남
(ArrayIndexOutOfBoundsException, NullPointerException,ClassCastException, ArithmeticException)
= 배열범위벗어남, null의 참조변수를 호출, 형변환실수, 정수를 0으로나눔

두가지의 명확한기준은 반드시 처리 해야하냐 말아야하냐의 차이이다.

Checked Exception이 발생할가능성있는 메소드는 반드시 try~catch 로 감싸거나 throw로 던져서 처리해야한다.
반면, Unchecked Exception은 명시적인 예외처리를 하지않아도된다.

자바에서 checked, unchecked exception 나눈이유

https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

메소드를 호출하는쪽은 그 메서드가 어떤 예외를 발생시킬수있는가에대해 반드시 알아야한다.
따라서 자바는 checked exception을 통해 해당 메서드가 발생시킬수있는 예외를 명세하도록 강제한다.

RuntimeException 은 예외를 명세하지않아도 되도록 한 이유
코드짠 개발자의 실수로인해 생기는 예외가 RuntimeException이어서, 클라이언트쪽에서(메소드호출) 이를 복구하거나 대처할수있을거라고 예상하기 힘들다. 또, 어디서든 매우빈번하게 발생할수있는게 RuntimeException 이기때문에 모든 Runtime Exception을 메서드에 명시하도록 강제하는것은 프로그램의 명확성을 떨어트릴수있다.

클라이언트가 exception을 회복할수있을거라고 예상되는경우 checked exception, 그렇지않은경우 unchecked exception 으로 만드는것이 좋다.

예외전파

메서드에서 에러가 발생한다
메서드는 에러에대한정보, 타입, 시점이 담긴객체를 만들고 런타임시스템에 전달한다. 그리고 이것을 예외를 던진다고 표현한다.

메서드가 예외를던지면 런타임시스템이 예외를 처리할 무언가를 찾기위해 시도한다


이미지 출처: https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html

Call stack = 예외가발생한 메서드에 도달하기 위해 호출된 메서드의 목록

오류가 발생한 메서드에 도달하기위해 콜스택을 이용하여 도달한다.


이미지 출처: https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html

런타임 시스템이 오류가 발생한 메서드에서 호출된 역순으로 Callstack을 타면서 예외를 처리할수있는 코드를 확인하고,
적절한 예외처리 핸들러가 발견되면 런타임시스템이 예외를 핸들러에 전달한다.

Exception을 처리할수있는 핸들러를 찾을떄까지 상위로 전달된다.
마지막 메인에서까지 에러를던진다면? 스택트레이스를 보여주고 그 쓰레드가 종료된다.

커스텀 예외는 언제쓰는것이좋은가? 예외비용에 대한 좋은글

https://tecoble.techcourse.co.kr/post/2020-08-17-custom-exception

스프링 전략에서 볼수있는 예외복구

JDBC를 사용했을때의 예외처리문이다.
어떠한 이유로 SQL예외가 발생했는지 하나씩 확인하고있다.
이러한 문제는 게다가 DB마다 예외상태코드가 다르기때문에 DB가 변경된다면 상태코드도 또 바꿔줘야한다.

try {
	//do data operation using JDBC
} catch (SQLException ex) {
	boolean recovered = false;
	String sqlstate = sqlex.getSQLState();
		if (sqlstate != null) {
		String classCode = sqlstate.substring(0, 2) ;
			if ("23".equals(classCode) ||"27".equals(classCode) ||
			 	"44".equals(classCode)) {
		// Apply recovery strategy
			recovered = true;
	}
}
if (!recovered)
	throw new ApplicationSpecificExceptionf("Other SQL exception", ex);
}

스프링은 DataIntegrityViolationException (데이터 바인딩이 잘못됨)이라는 예외를 제공한다.

이는 JDBC의 SQLException보다 훨씬더 의미를 명확하게 알수있으며,
의미를 명확하게 알수있는장점뿐만아니다.

try {
	//do data operation using JDBC abstraction layer
} catch (DatalntegrityViolationException ex) {
	// Apply recovery strategy
}

또하나의 장점은
명확한 에러를 전달했으니, 복구할수있으면 복구해봐라 하는 전략을 catch문에 작성할수있다.
복구전략을위한 catch로직을 짤수있다.

try-with-resources

try-catch-finally

    	DataInputStream dis = null;
        FileInputStream fis = null;

        try {
            fis = new FileInputStream("123.txt");
            dis = new DataInputStream(fis);
              ...
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(dis!=null)
                    dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

try-with-resources

        try(FileInputStream fis = new FileInputStream("123.txt");
        DataInputStream dis = new DataInputStream(fis)) {
            ...
        } catch (IOException e) {
            e.printStackTrace();
        }
  • 코드가독성
  • 만약 자원을 하나 더 close()해서 반환해야하는데 첫번째 close()에서 unchecked exception이 발생하면 두번째 close()로 가지않는다.( 의도한 흐름대로 진행되지않을수있다.)
  • finally도 사용할수있다.

좋은 웹페이지 즐겨찾기