예외처리 (Exception)
프로젝트 개발 혹은 공부 중 발생하는 Exception에 대해 정리해보자.
[ 예외 (Exception) ]
- 사용자 혹은 개발자의 잘못으로 발생하는 오류, 처리 가능한 에러
- 에러 발생시 지속적인 서비스 제공하기 위함
- 종류
- 일반 예외 : 컴파일 체크 계열( Class . . . , )
- java.lang.RuntimeException 외의 모든 예외 클래스
- 제약 조건 : try ~ catch 블록으로 처리 필수
- 실행 예외
- java.lang.RuntimeException 상속받는 모든 예외 클래스
- try ~ catch 옵션
- 일반 예외 : 컴파일 체크 계열( Class . . . , )
1. Exception의 종류
1-1. NullPointerException
String str = null;
System.out.println(str.length()); // Error
- 접근한 Object가 null 값일 때 발생한다.
1-2. NumberFormatException
String str = "three";
Integer.parseInt(str); // Error
- 문자열을 숫자형으로 변환 시 발생한다.
1-3. ArrayIndexOutOfBoundsException
int[] intArr = { 1, 2, 3 };
System.out.println(intArr[3]); // Error
- 범위 밖의 배열 지정 시 발생한다.
1-4. ClassCastException
class A{}
class B extends A{}
class C extends A{}
public class TestException {
public static void main(String[] args) {
A a = new B();
B b = new B();
C c = (C)a; // Error
}
}
- 클래스 형변환 연산을 잘 못 했을 때 발생한다.
1-5. ArithmeticException
int i2 = 10/0; // Error
- 제로제산 등 산술 예외 시 발생한다.
1-6. . . .(지속적으로 추가하기)
2. 예외처리 방법
java에서는 대표적으로 try ~ catch 문을 통한 예외처리를 한다.
2-1. try ~ catch 기본형
try {
// Error가 발생할 수 있는 코드 or 블럭
예외 발생 가능성 존재하는 코드;
} catch (Exception e) {
// Error 발생시 수행
예외 처리 코드;
}
- 기본적으로 try 문을 먼저 실행하며, Error가 발생하지 않으면 catch 문은 실행되지 않는다.
- try 문에서 Error가 발생하면 해당 라인까지만 try문을 진행하며, catch 문이 실행된다.
2-2. multi-catch
try {
String str1 = "three";
Integer.parseInt(str1); // NumberFormatException
String str2 = null;
System.out.println(str2.length()); // NullPointerException
} catch (NumberFormatException | NullPointerException e) {
e.printStackTrace();
System.out.println(e.getMessage());
System.out.println("예외 발생 : NumberFormatException");
} catch (Exception e) {
System.out.println("예외 발생 : NullPointerException");
}
- 하나의 try 블록에서 여러개의 예외가 발생하는 경우 많은 catch블럭이 필요하다.
- Exception 하나로 묶어서 처리할 수도 있지만, 불가피한 경우 multi-catch문을 통해 상황별로 나눌 수 있다는 장점이 있다.
2-3. try ~ catch ~ finally
try {
예외 발생 가능성 존재하는 코드;
} catch(발생 가능성 존재하는 예외 Exception 변수) {
예외 처리 코드;
} finally {
예외 발생 여부와 무관, 무조건 실행되는 블럭
주로 자원 반환 로직으로 많이 사용됨
(ex. DB 접속 해제)
}
- 구조는 try ~ catch 문과 동일하며, 추가적으로 finally 문은 try ~ catch의 결과와 상관없이 마지막에 무조건 실행되는 블럭이다.
3. 개발 상황에 따른 예외 발생 문법
3-1. body{ } 영역에 throw new 생성자명( [...] ); 구현
try {
예외 발생 가능성 존재하는 코드;
throw new Exception;
} catch(발생 가능성 존재하는 예외 Exception 변수) {
예외 처리 코드;
}
- 강제로 예외를 발생시킬 때 사용한다.
3-2. 메소드 선언구에 발생 가능성 예외 알림 표기
반환타입 메소드명( [...] ) throws ~Exception[, ~Exception2 ]{ }
public static void method() throws Exception { // throws 여러개 가능
Class clazz = Class.forName("java.lang.String2");
}
public static void main(String[] args) {
try {
method();
} catch(발생 가능성 존재하는 예외 Exception 변수) {
예외 처리 코드;
}
}
- 예외처리를 책임전가 할 때 사용한다.
- [ 중요 ] main() 메소드에서도 throws 키워드를 사용하여 예외를 떠넘길 수 있지만, main() 메소드에서 throws Exception을 붙이는 것은 좋지 못한 예외 처리 방법이다.
- main() 메소드에서는 try ~ catch 블록으로 예외를 최종 처리하는 것이 바람직하다.
4. 사용자 정의 예외 클래스 ( Application Exception )
기본 생성자
String 매개변수 존재 생성자
- 사용자 정의 예외 클래스는 컴파일러가 체크하는 일반 예외로 선언할 수 있다.(Exception)
- 혹은 컴파일러가 체크하지 않는 실행 예외로 선언할 수도 있다. (RuntimeException)
public class MyException extends Exception { // Exception or RuntimeException
public MyException() {}
public MyException(String str) {
super(obj); // super는 반드시 명시적으로 존재해야 한다.
}
}
- 사용자 정의 예외 클래스 명명은 일종의 개발자 사이의 규칙으로 Exception으로 끝나야 한다.
- 생성자는 일반적으로 기본 생성자와 예외 발생 원인 전달을 위한 String 타입 파라미터를 갖는 생성자이다.
5. 예외처리 예제
- 다음은 XX은행의 통장이다.
public class TestException2 {
static int balance = 50; // 잔액 -> 기초 잔액 설정
static int deposit; // 입금액
static int withdraw; // 출금액
// 입금 메소드
static void plus(int deposit) {
try {
// 입금액이 0원이상이면 정상거래
if (deposit >= 0) {
balance = balance + deposit;
} else {
// 입금액이 0원 이하면 Error
throw new ArithmeticException();
}
} catch (ArithmeticException e) {
System.out.println("비정상적인 금액 입력입니다.");
System.out.println("입금이 취소되었습니다.");
} finally {
System.out.println("거래가 종료되었습니다.");
}
}
// 출금 메소드
static void minus(int withdraw) {
try {
if (withdraw >= 0) {
if (balance - withdraw >= 0) {
balance = balance - withdraw;
System.out.println(withdraw + "원이 출금되었습니다.");
} else {
// 출금 후 잔액이 0원 이하면 Error
throw new ArithmeticException();
}
}
} catch (ArithmeticException e) {
System.out.println("비정상적인 금액 입력입니다.");
System.out.println("출금이 취소되었습니다.");
} finally {
System.out.println("거래가 종료되었습니다.");
}
}
public static void main(String[] args) {
plus(50);
System.out.println("잔액은 " + balance);
System.out.println("----------------------------");
minus(150);
System.out.println("잔액은 " + balance);
}
}
출력창
거래가 종료되었습니다.
잔액은 100
----------------------------
비정상적인 금액 입력입니다.
출금이 취소되었습니다.
거래가 종료되었습니다.
잔액은 100
'Java' 카테고리의 다른 글
Iterator in java (0) | 2021.02.01 |
---|
댓글