티스토리 뷰
Exception과 Error의 차이는?
프로그램에서 Error는 어떤 원인에 의해서 오작동을 하거나 비정상적으로 종료되는 경우를 말한다.
이를 발생시점에 따라서 컴파일 에러 (compile-time error)와 런타임 에러(runtime error)로 나눌 수 있다.
이외에도 논리적 에러(logical error)가 있는데 이건 컴파일도 잘되고 실행도 잘 되지만 논리적으로 맞지 않는 에러일 때 해당된다.
자바에서는 에러 이외의 예외(exception)이라고 부르는 오류가 있다.
예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다.
에러는 메모리 부족(OutOfMemoryErro)이나 스택오버플로우(StackOverflowError)와 같이 일단 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습될 수 있는 비교적 덜 심각한 것이다.
에러가 발생하면 프로그램의 비정상적인 종료를 막을 길이 없지만 예외는 발생하더라도 적절한 예외 처리 코드를 작성해서 비정상적인 종료를 막을 수 있다.
자바가 제공하는 예외 계층 구조
자바에서는 예외를 클래스로 관리한다.
JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다.
그리고 나서 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해준다. 모든 예외 클래스들은 java.lang.Exception 클래스를 상속받는다.
모든 예외 클래스는 Throwable 클래스를 상속받는다.
이런 예외 계층 구조를 아는 것은 Catching Exception 할 때 유용하다.
Error 클래스는 시스템 레벨의 심각한 수준의 Error를 의미한다. 이것은 개발자가 어떻게 손을 써서 해결할 수 없는 수준의 에러이다.
반면에 Exception 클래스는 개발자가 로직을 추가하여 오류를 미연에 방지할 수 있다.
RuntimeException과 RE가 아닌 것의 차이는?
Exception 클래스는 많은 자식 클래스들을 가지고 있는데 RuntimeException은 CheckedException과 UncheckedException을 구분하는 기준이다. Exception의 자식 클래스 중에서 RuntimeException을 제외한 모든 클래스는 CheckedException 이며, RuntimeException과 그의 자식 클래스들을 UncheckedException이라고 한다.
Checked Exception (RuntimeException 클래스들을 제외한 나머지 클래스)
주로 외부의 영향으로 발생하는 것들로, 프로그램 사용자들의 동작에 의해서 발생하는 경우가 많다.
- 반드시 예외 처리를 해야 한다.
Unchecked Exception
주로 개발자의 코딩중에 발생될 수 있는 예외들
- ArrayIndexOutOfBoundsException (배열의 범위를 벗어남)
- NullPointerException (null 값에 . 찍었을 때)
- ArithmeticException ( 숫자 연산 관련..)
- 명시적인 처리를 강제하지 않는다.
- 실행되는 시점(Runtime)에 확인한다.
자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
RuntimeException은 컴파일러가 체크해주지 않기 때문에 개발자가 직접 예외처리 코드를 작성해야 한다.
자바에서 예외처리 코드는 try-catch-finally 블록을 이용한다.
try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성되어 일반 예외와 실행 예외가 발생할 경우 예외 처리를 할 수 있도록 해준다.
@Test
void ExceptionTest(){
try {
TODO 예외 발생 가능 코드
} catch (Exception e) {
TODO 예외 처리
} finally {
TODO 항상 실행
}
}
try 블록에는 예외 발생 가능 코드가 위치한다. try 블록 코드가 예외 없이 잘 실행되면 catch 블록은 실행되지 않고 finally 블록이 실행된다.
예외가 발생하면 즉시 실행을 멈추고 catch 블록으로 이동하여 예외 처리 코드를 실행한다. 그리고 finally 블록의 코드를 실행한다.
finally 블록은 옵션으로 생략이 가능하고 finally 블록은 예외 발생 여부에 상관없이 항상 실행해야 될 내용이 있을 경우에만 작성해줘도 된다.
try catch 블록에서 return 문을 사용해도 finally 블록은 실행이 된다.
기본적으로 try catch 블록에서는 예외가 발생하면 Catch 블록으로 이동하여 예외 코드를 실행하는데 만약 예외가 2개 이상이면 어떻게 할까?
다중 catch 블록
public class ExceptionStudy {
public static void main(String[] args) {
try {
int[] arr = new int[2];
arr[3] = 10;
int a = 10, b=0;
int divide = a / b;
System.out.println("divide = " + divide);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
}
코드를 살펴보면 배열의 크기를 넘어서는 값을 배열에 담으려고 하면 ArrayIndexOutOfBoundsException 가 실행된다.
그리고 산술연산 Exception중에 ArithmeticException은 정수 값을 0으로 나누려고하면 실행이된다.
보통 이런식으로 코딩하지는 않겠지만 예외가 발생할 수 있는 코드가 여러 개 있으면 다중 catch 블록을 사용하면된다.
다중 catch 블록을 사용할 때 주의할 점은 상위 예외 클래스가 하위 예외 클래스보다 아래쪽에 위치해야 한다.
try 블록에서 예외가 발생했을 때 catch 블록은 위에서부터 차례대로 검색이 되는데 만약 가장 상위 예외 클래스의 catch 블록이 있으면 하위의 예외 클래스 catch 블록은 실행되지 않는다.
자바의 모든 예외 클래스는 상위 클래스인 Exception을 상속받기 때문에 첫 번째 catch 블록만 실행이된다.
Intellij IDE 에서는 아예 컴파일 오류가 난다.
public class ExceptionStudy {
public static void main(String[] args) {
try {
int[] arr = new int[2];
arr[3] = 10;
} catch (Exception e) {
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
친절하게도 어떻게 작성해야 할지 다 알려준다.
멀티 catch 블록
자바 7부터는 catch 블록을 하나의 catch 블록에서 여러 개의 예외 처리할 수 있도록 멀티(Multi) catch 기능을 추가했다.
catch 괄호 안에 동일하게 처리하고 싶은 예외를 |로 연결하면 된다.
public class ExceptionStudy {
public static void main(String[] args) {
try {
int[] arr = new int[2];
arr[3] = 10;
int a = 10, b=0;
int divide = a / b;
System.out.println("divide = " + divide);
} catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
e.printStackTrace();
}
}
}
try-with-resource
자바 7에서부터 또 새로 추가 된 try-with-resource를 사용하면 예외 발생 여부와 상관없이 사용했던 리소스 객체 (각종 입출력 스트림, 서버 소켓, 소켓, 각종 채널) 의 close() 메소드를 호출해서 안전하게 리소스를 닫아준다.
try-with-resource를 사용하기 위해서는 해당 리소스 객체가 java.lang.AutoCloseable 인터페이스를 구현하고 있어야한다.
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("")){
}catch(IOException e){
}
}
try(){} 형태로 사용이 가능하고 ()안에 들어올 수 있는 건 AutoCloseable을 구현한 구현체만 가능하다.
라이브 방송중 나온 코드
public class Example {
public static void main(String[] args) {
try (MyStream myStream = new MyStream()) {
System.out.println("hello");
} finally {
System.out.println("finally");
}
}
}
AutoCloseable 구현
public class MyStream implements AutoCloseable {
@Override
public void close() throws RuntimeException {
System.out.println("Auto close");
}
}
컴파일된 클래스
확인해보면 try 밑에 myStream.close()를 호출한다. 만약 예외가 발생했더라도 catch 안에서 또 try문에서 close()메소드를 호출한다.
public class Example {
public Example() {
}
public static void main(String[] args) {
try {
MyStream myStream = new MyStream();
try {
System.out.println("hello");
} catch (Throwable var9) {
try {
myStream.close();
} catch (Throwable var8) {
var9.addSuppressed(var8);
}
throw var9;
}
myStream.close();
} finally {
System.out.println("finally");
}
}
}
예외 떠넘기기 throws
자바의 예외 처리 방법은 예외가 발생한 지점에서 try-catch를 사용하지 않고 예외가 발생한 메소드를 호출한 지점으로 예외를 전달하여 처리하는 방법이 있다. 이때 사용하는 키워드가 throws 키워드이다.
throws 키워드는 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역할을 한다.
throws 키워드 뒤에는 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 된다.
만약 모든 메서드에서 throws를 이용해서 예외를 떠넘기다보면 최초 호출 지점인 main() 메소드로 예외가 던져지게 되고 main() 메소드 마저 예외를 떠넘기면 결국 JVM이 최종적으로 예외처리를 하게된다.
main() 메소드에서 throws Exception을 붙이는 것은 좋지 못한 예외 처리 방법이다.
public class ExceptionThrows {
public static void main(String[] args) {
try {
findClass();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void findClass() throws ClassNotFoundException {
Class clazz = Class.forName("java.lang.String2");
}
}
커스텀한 예외 만드는 방법
사용자 정의 예외는 개발자가 직접 정의해서 만드는 Exception 이다.
www.baeldung.com/java-new-custom-exception
참고
자바의 정석 - www.yes24.com/Product/Goods/24259565?OzSrank=2
이것이 자바다 - www.yes24.com/Product/Goods/15651484
Nextree - www.nextree.co.kr/p3239/
- Total
- Today
- Yesterday
- 북리뷰
- JavaScript
- LocalDate
- Github Status
- intellij
- mybatis
- Mac
- jQuery
- springboot
- Linux
- Spring
- localtime
- rocky
- Java
- svn
- Bash tab
- docker
- input
- oracle
- k8s
- 오라클
- window
- Spring Security
- LocalDateTime
- maven
- mybatis config
- config-location
- 베리 심플
- Kotlin
- elasticsearch
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |