- 해당 내용은 백기선 님의 자바 온라인 스터디 공부 및 제출 목적
-> https://github.com/whiteship/live-study/issues/9
목표
자바의 예외 처리에 대해 학습하세요.
학습할 것 (필수)
- 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
- 자바가 제공하는 예외 계층 구조
- Exception과 Error의 차이는?
- RuntimeException과 RE가 아닌 것의 차이는?
- 커스텀한 예외 만드는 방법
* 예외
- Java 에서 예외를 얘기할때는 예외(Exception)와 오류(Error)로 나뉘어 진다.
1. 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
- 프로그램에서 예외가 발생하면, Error 든 Exception 이든 어플리케이션을 종료시키게 된다.
- 이때, 개발자들은 어플리케이션을 강제로 종료 시킬 것인가, 아니면 일단 넘겨서 다른 작업을 진행할 것인가를 구현할 수 있다.
- 대부분의 어플리케이션에서는 예외처리를 하여 정상적인 작동을 유지하여 갑작스런 종료를 막고, 서비스를 유지할 수 있도록 코드를 구현할 것이다.
1-1. 기본 try-catch-finally 문
public static void main(String[] args) {
try {
// 처리 로직
} catch (예외클래스 e) {
// 예외 발생시 처리 로직
} finally {
// 정상 진행 또는 예외 발생시에도 항상 실행될 마지막 로직
}
}
- try 블록에서는 예외 발생 가능성이 있는 코드를 작성.
- catch 블록에서는 예외 발생 시 진행할 코드를 작성.
- finally 블록에서는 예외 발생에 상관없이 무조건 실행할 코드를 작성.(해당 블록은 생략 가능)
- try 블록에서 예외 발생이 하지 않는다면, catch 블록을 거치지 않고, 바로 finally 블록 코드를 실행.
- try 블록에서 예외가 발생한다면, catch 블록으로 넘어가 코드를 실행 후, finally 블록 코드 실행.
1-2. try-다중 catch 문
- 하나의 try 블럭에 여러개의 catch 블럭을 작성할 수 있다.
public static void main(String[] args) {
try {
// 처리 로직
} catch (예외클래스1 e1) {
// 예외1 발생시 처리 로직
} catch (예외클래스2 e2) {
// 예외2 발생시 처리 로직
} finally {
// 정상 진행 또는 예외 발생시에도 항상 실행될 마지막 로직
}
}
- 다중 catch 블록을 작성할 때는, 상위 예외클래스가 하위 예외클래스보다 아래에 위치해야 한다.
- 하위 예외클래스가 상위 예외클래스에 속해있으므로, 상위 예외클래스 뒤에 코드를 구현할 필요가 없다.
- 예외 발생 시 하나의 catch 블록에 걸리게 된다면 이후 catch 블록은 실행하지 않는다.
- 위의 그림은 모두 ArithmeticException이 발생한다.
- 좌측은 상위 예외클래스인 Exception이 먼저 있기 때문에 ArithmeticException 블록은 코드 자체가 무의미하다.
- 우측은 하위 예외클래스인 ArithmeticException가 먼저 있기 때문에 실행이되며 이후 Exception 블록은 실행되지 않는다.(하지만 try 블록에서 ArithmeticException이 아닌 다른 예외 발생시 Exception 블록이 실행될 것이다.)
1-3. try-멀티 catch 문
- 하나의 try 블럭에 멀티 catch 블럭을 작성할 수 있다.
public static void main(String[] args) {
try {
// 처리 로직
} catch (예외클래스1 e1 || 예외클래스2 e2) {
// 예외1 또는 예외2 발생시 처리 로직
} finally {
// 정상 진행 또는 예외 발생시에도 항상 실행될 마지막 로직
}
}
1-4. throw
- thorw 키워드는 개발자가 고의로 예외를 발생시킬 때 사용.
public static void main(String[] args) {
int a = 1;
if(a == 1){
throw new Exception();
}
}
- 위 코드에서와 같이 어떠한 상황이 있을때 강제로 예외를 발생시킬 수 있다.
- throw 키워드를 통해서 커스텀하여 만든 Exception을 발생시키기도 한다.
1-5. throws
- throws 키워드는 메소드의 예외를 선언할 수 있게 한다.
public static void method() throws Exception {
// 처리 로직
}
- throws는 메소드 선언부에 예외를 선언함으로써 해당 메소드에서 개발자가 어떤 예외를 처리해야 하는 지 알려주는 역할을 가진다.
- throws는 해당 메소드에서 해당 예외를 처리하지 않고, 해당 메소드를 사용(호출)하는 쪽에서 예외를 처리하도록 책임을 전가한다.
public static void main(String[] args) {
try {
throwsTest();
} catch (ArithmeticException e){
// throwsTest 던진 예외를 받아 처리
}
}
public static int throwsTest throws ArithmeticException {
// ArithmeticException 예외 발생 -> throwsTest를 호출한 main 메소드로 예외 전달
System.out.println(1/0);
}
2. 자바가 제공하는 예외 계층 구조
- Java 에서는 실행 시 발생할 수 있는 오류를 클래스로 정의한다.
- 에러(Error) 와 예외(Exception)의 상속 계층 구조는 아래와 같다.
- Unchecked Exception
- Unchecked Exception은 RuntimeException을 상속받은 Exception.
- 일반적으로 발생을 예측할 수 없고 복구할 수 없는 예외.
- programming errors나 외부 API 사용 때문에 발생. - Checked Exception
- Exception의 하위 클래스 중 RuntimeException을 제외한 Exception을 상속받은 Exception.
- 해당 예외는 예상할 수 있고 처리 가능. - Error
- Error 클래스의 하위 클래스들이 Error
- Error 는 예상할 수 없고 복구할 수 없다.
3. Exception 과 Error의 차이는?
- 예외(Exception)
- 개발자가 구현한 로직에서 발생.
- 개발자가 구현한 로직 내부에서 발생하기 때문에 예외발생 상황을 미리 예측하여 처리 가능.
- Checked Exception 과 Unchecked Exception 이 존재 - 오류(Error)
- 시스템의 비정상적인 상황으로 발생.
-시스템 레벨에서 발생하기 때문에 심각한 수준.
- 시스템의 메모리 부족(Out of Memory), 스택오버플로우(Stack Overflow) 등과 같이 JVM이나 서버의 시스템 문제로 발생.
- 개발자가 오류발생 상황을 미리 예측하여 처리 불가능.
- 오류가 발생하는 순간 프로그램(서비스)이 비정상 종료가 되므로 발생하지 않도록 해야함.
4. RuntimeException과 RE가 아닌 것의 차이는?
- Java에서 RuntimeException은 Unchecked Exception으로 RuntimeException이 아닌 것은 Checked Exception으로 분류.
- Checked Exception
- 컴파일 시점에서 확인될 수 있는 예외.
- 예외를 예측 및 복구 가능(try-catch 사용).
- 해당 예외는 반드시 처리 하거나 메소드 선언부에 예외 선언 필요.
public static void main(String[] args) {
// 1. Checked Exception 발생
// 컴파일시 ClassNotFoundException 발생하여 프로그램 실행되지 않음.
// try-catch로 해당 Exception 처리 필요
Class test = Class.forName("java.lang.StringTest");
// 2. Checked Exception 발생 처리
try {
Class test = Class.forName("java.lang.StringTest");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException 에러 처리");
}
}
- Runtime Exception(Unchecked Exception)
- 컴파일 단계에서 확인되지 않는 예외.
- 컴파일 단계에서 알수가 없기 때문에 개발자의 경험과 테스트를 통해서 해당 예외를 알아서 처리 필요.
- Checked Exception과 다르게 예외처리를 강제로 지정하지는 않는다.
public static void main(String[] args) {
// 1. UnChecked Exception 발생
// 컴파일시 아무 이상 없음.
// 해당 메소드 실행시 ArrayIndexOutOfBoundsException 발생
int[] a = {1,2,3};
System.out.println(a[5]);
// 2. UnChecked Exception 발생 처리
try {
int[] a = {1,2,3};
System.out.println(a[5]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException 에러 처리");
}
}
- 클라이언트가 Exception을 적절히 회복할 수 있을 것이라고 예상되는 경우 Checked Exception으로 만들고, 그렇지 않을 경우에는 UnChecked Exception으로 만드는 것이 좋다..
5. 커스텀한 예외 만드는 방법
- 기존에 정의된 예외 클래스 외에 개발자의 필요에 따라 새로운(커스텀) 예외를 정의 가능.
- Exception 클래스를 상속받거나, 알맞은 예외 클래스를 상속받아야만 한다.
public class ExceptionTest {
public static void main(String[] args) throws CustomException {
test("Exception");
}
public static void test(String text) throws CustomException {
if (!text.equals("Exception")) {
throw new CustomException("CustomException 발생");
}
}
}
class CustomException extends Exception {
// 기본 생성자
public CustomException(){}
public CustomException(String message) {
// 상위 클래스인 Exception의 생성자 호출
super(message);
}
}
참고
'Study > Java(Online-Study)' 카테고리의 다른 글
8주차 과제: 인터페이스 (0) | 2021.07.19 |
---|---|
7주차 과제 : 패키지 (0) | 2021.07.19 |
6주차 과제: 상속 (0) | 2021.07.17 |
5주차 과제: 클래스 - 이론(1) (0) | 2021.06.27 |
4주차 과제: 제어문 - 이론(1) (0) | 2021.06.20 |