자바 study(jdeep) 발표 - exception
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도 사용할수있다.
Author And Source
이 문제에 관하여(자바 study(jdeep) 발표 - exception), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dudwls0505/자바발표저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)