목표
자바의 예외 처리에 대해 학습하세요.
학습할 것
-
자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
-
자바가 제공하는 예외 계층 구조
-
Exception과 Error의 차이는?
-
RuntimeException과 RE가 아닌 것의 차이는?
-
커스텀한 예외 만드는 방법
자바가 제공하는 예외 계층 구조
- 자바는 실행시 발생할 수 있는 오류를 클래스로 정의하였다.
오류를 발생 시점에 따라 컴파일 에러, 런타임 에러, 논리적 에러로 분류 할 수 있다.
에러(Error) : 프로그램 코드에 의해서 수습이 불가능한 심각한 오류
예외(Exception) : 프로그램 코드에 의해서 수습이 가능한 오류
try-catch 오류
try부분에서 오류가 발생하면 객체가 생성되고, catch부분이 True가 되어 catch 블럭 아래의 코드가 실행됨
예외 발생 원인을 알기 위한 메소드
printStackTrace() : 호출 스택에 있었던 정보와 예외 메세지 출력
getMessage() : 발생한 예외 클래스의 인스턴스에 저장된 메세지
멀티 catch 블럭 - JDK1.7 하나의 catch블럭으로 합칠 수 있음
"|" 기호로 연결된 예외 클래스가 조상과 자손의 관계에 있으면 컴파일 에러가 발생함
Throw 예외
public class ThrowException {
public static void main(String[] args) {
try{
Exception a = new Exception("오류 발생");
throw a;
// 위 두줄과 같은 의미 throw new Exception ("오류 발생");
}catch(Exception a){
System.out.println("에러 메세지 " + a.getMessage());
// a.printStackTrace();
}
System.out.println("--------------The End----------------");
}
}
RuntimeException 클래스에 속하는 예외는 예외처리를 강제하지 않는다. -> unchecked예외
- 프로그래머가 실수로 발생하는 예외이다.
만약 예외 처리를 해야 한다면?
아래와 같이, 참조 변수와 배열이 사용되는 모든 곳에 예외처리를 해야할 것이다.
try{
int[] arr = new int[10];
System.out.println(arr[0]);
}catch(IndexOutOfBoundsException ie){
}
Throws 예외
메서드에 예외를 선언하는 방법
void method() throws Exception1, Exception2,...
메서드 내에 발생할 가능성이 있는 예외를 메서드의 선언부에 명시 -> 사용하는 쪽에서 처리를 강요함
코드상에서 try- catch구문을 수행하지 않으면 에러 발생!
finally 구문
예외 발생 여부와 상관 없이 실행.
try -> catch -> finally
try -> finally
커스텀한 예외 만드는 방법
class MyException extends RuntimeException{
// Exception 클래스를 안쓰는 이유: try -catch 문을 빼서 코드의 복잡성을 낮추기 위함
MyException(String msg){
super(msg); // 조상인 RuntimeException 클래스의 생성자를 호출한다.
}
클래스 생성 방법과 동일하고 String msg를 Exception 클래스들에서 상속받는다.
Exception 클래스 혹은 RuntimeException 클래스를 상속 받는다.
public class CustomizeExceptionDemo {
public static void main(String[] args) {
try{// payMoney()가 Exception 클래스를 상속받으므로 try- catch문 안에 없을 시 에러 발생
payMoney();
}catch(LeakMoney LM){
System.out.println("발생한 에러는:" + LM.getMessage());
}catch (LeakPoint LP){
System.out.println("발생한 에러는:" + LP.getMessage());
}
}
public static void payMoney() throws LeakMoney, LeakPoint{
if(!enoughMoney()){ throw new LeakMoney("잔액이 부족합니다.");}
if(!enoughPoint()){throw new LeakMoney("포인트가 부족합니다.");}
}
private static boolean enoughPoint() {
return true;
}
private static boolean enoughMoney() {
return false;
}
class LeakPoint extends Exception{
public LeakPoint(String message) {
super(message);
}
}
static class LeakMoney extends Exception{
public LeakMoney(String message) {
super(message);
}
}
}
이런식으로 하나의 메서드에 두 개의 에러를 발생시킬 수 있다.
※예외를 발생한 메서드와 호출한 메서드에서 양쪽으로 처리해야 할 경우 : exception re-throwing
public class re_Throwing {
public static void main(String[] args) {
// 호출한 메서드 내에서도 발생
try{
method();
}catch(Exception e){
System.out.println("main에서 예외가 처리 되었습니다.");
}
}
static void method() throws Exception{
//메서드 내 에서도 발생
try{
throw new Exception();
}catch(Exception e){
System.out.println("method 에서 예외가 처리 되었습니다.");
throw e;
}
}
}
Chained exception
※ 여러가지 예외를 하나의 분류로 만드는 방법 :
A를 B의 원인 예외(cause exception)으로 만든다 !
위의 CustomizeException 에 2가지 예외의 원인이 되는 예외를 생성한다.
static class InstallException extends Exception{
public InstallException(String message) {
super(message);
}
}
InstallException을 상속받는 메서드를 추가한다.
static void install() throws InstallException{
try{
payMoney();
}catch(LeakMoney LM){
InstallException ie = new InstallException("결제 중 예외 발생");
ie.initCause(LM);
throw ie;
}catch(LeakPoint LP){
InstallException ie = new InstallException("결제 중 예외 발생");
ie.initCause(LP);
throw ie;
}
}
Main문을 변경한다.
public static void main(String[] args) {
try{
install();
}catch(InstallException ie){
ie.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
'Java > Study' 카테고리의 다른 글
[JAVA] 로컬 클래스 , 익명 클래스, 람다의 스코프 차이 (0) | 2021.01.25 |
---|---|
[JAVA]백기선 라이브 스터디 10주차 - Thread (0) | 2021.01.21 |
[JAVA]백기선 라이브 스터디 8주차 (0) | 2021.01.08 |
[Java]백기선 라이브 스터디 7주차 (0) | 2021.01.02 |
[Java] 백기선 라이브 스터디 6주차 과제 (0) | 2020.12.26 |