[Java] 예외
목차
1. 오류와 예외
2. 예외 발생
3. 예외 처리
4. Exception 클래스
5. 변수 e
Error vs Exception
시스템이 동작하는 도중 예상치 못한 상황이 발생해 실행 중인 프로그램이 영향을 받는 것을 오류와 예외 2가지로 구분할 수 있다.
오류(error)
· 시스템에 비정상적인 상황이 생겼을 때 발생
· 시스템 레벨에서 프로그램에 수습할 수 없는 심각한 문제를 야기해 실행 중인 프로그램을 종료시킨다.
· 개발자가 미리 예측해 처리 불가
예외(exception)
· 개발자가 구현한 로직이나 사용자에 의해 발생
· 실행 중인 프로그램을 비정상적으로 종료시킨다.
· 개발자가 미리 예측해 처리 가능 -> 상황에 맞는 예외 처리
=> 예외가 발생하면 자바 플랫폼이 가장 먼저 인지하여, 응용 프로그램에게 전달
=> 응용 프로그램에 예외에 대한 대처 코드가 없다면, 강제 종료
예외가 발생하는 이유
예외는 왜 발생할까?
프로그램이 실행하는 동안 개발자가 설계한 의도대로 운영되지 않았기 때문일 것이다.
[예시]
- 정수를 0으로 나누는 경우
- 배열의 길이보다 큰 인덱스로 배열의 원소를 접근하는 경우
- 존재하지 않는 파일을 열려고 하는 경우
- 정수 입력을 기다리는 코드가 실행되고 있을 때, 사용자가 문자를 입력한 경우
public class ExceptionApp {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2/0); //ArithmeticException
System.out.println(3);
}
}
실행결과
· 숫자를 0으로 나누는 경우 예외로 처리
· 실행 중 발생한 예외의 종류가 ArithmeticException임을 알려준다.
예외 처리
예외가 발생한 뒤에도 작업을 실행하려면 어떻게 해야 할까?
try-catch 문을 이용하면 예외가 발생해도 끝까지 실행할 수 있다.
try-catch-finally 문
try{
예외 발생 가능성이 있는 코드;
} catch(처리할 예외타입 선언) { //예외마다 하나씩 작성
예외 처리 코드;
} finally { //생략 가능
예외 발생 여부와 상관없이 무조건 실행되는 코드;
}
· try 문에서 예외가 발생하면 남은 코드를 실행하지 않고, 해당 예외 타입과 일치하는 catch 문 실행
** 다른 제어문과 달리 예외 처리문은 중괄호 생략 불가
자바에서는 Exception 클래스를 제공하여 예외를 처리할 수 있게 한다.
public class ExceptionApp {
public static void main(String[] args) {
System.out.println(1);
try {
System.out.println(2/0);
}catch(ArithmeticException e) {
System.out.println("잘못된 계산");
}
System.out.println(3);
}
}
실행결과
public class ExceptionApp {
public static void main(String[] args) {
System.out.println(1);
int[] scores= {10, 20, 50};
try {
System.out.println(2);
System.out.println(scores[3]); //ArrayIndexOutOfBoundsException
System.out.println(2/0); //ArithmeticException
} catch(ArithmeticException e) {
System.out.println("잘못된 계산");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("없는 값");
}
System.out.println(3);
}
}
실행결과
· 다수의 예외를 처리하는 경우, 여러 개의 catch 문을 연속적으로 작성 가능
· 예외가 발생하면 try 문과 가까운 catch 문부터 순회하면서 해당 예외와 타입이 일치하는 catch 문을 실행
-> catch 문의 위치 중요
· 더 좁은 범위의 예외를 처리하는 catch 문을 먼저, 더 넓은 범위의 예외를 처리하는 catch 문을 나중에 명시
· 예외를 처리하면 마지막 숫자 3까지 출력하고 프로그램 종료
Exception 클래스
예외상황마다 개별적으로 취해야 할 작업이 없거나 어떤 예외가 나올지 예측할 수 없다면 어떻게 해야 할까?
-> Exception 클래스 이용
예외도 클래스로 구현되어 있다.
ex) ArithmeticException 클래스의 Java API 문서
· RuntimeException의 자식 클래스
· RuntimeException은 Exception 클래스의 자식 클래스
-> 여러 예외가 존재해도 Exception 클래스를 이용해 포괄적인 처리 가능
public class ExceptionApp {
public static void main(String[] args) {
System.out.println(1);
int[] scores= {10, 20, 50};
try {
System.out.println(2);
System.out.println(scores[3]); //ArrayIndexOutOfBoundsException
System.out.println(2/0); //ArithmeticException
} catch(ArithmeticException e) {
System.out.println("잘못된 계산");
} catch(Exception e) {
System.out.println("이상 발생");
}
System.out.println(3);
}
}
실행결과
· try 문에서 발생한 ArrayIndexOutOfBoundsException은 catch 문을 순회
-> Exception을 포괄적으로 잡는 catch 문 실행
catch 문의 변수 e
catch 문의 변수 e도 인스턴스인데 이를 이용해 무엇을 할 수 있을까?
catch 문의 변수 e
· 예외 클래스의 객체
· 예외 발생 원인, 발생 위치 등에 대한 정보들이 들어있다.
-> 프로그램의 어디서 왜 예외가 발생했는지 알 수 있다.
=> 예외가 발생하면 자바는 catch를 호출하면서 인자로 예외 클래스의 인스턴스를 전달
=> e를 통해 예외 클래스의 변수나 메소드를 호출 가능
getMessage 메소드를 이용하면 예외 상황에 대한 상세한 정보를 얻을 수 있다.
자세한 메소드의 종류는 Throwable 클래스의 설명서에서 확인할 수 있다.
https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#constructor.summary