프로그램이 실행 중 어떤 원인에 의해 오작동 하거나 비정상적으로 종료되는 경우를 말한다.
에러의 종류는 다음과 같다.
컴파일 에러 - 컴파일시 발생하는 에러
런타임 에러 - 실행 시에 발생하는 에러
논리적 에러 - 실행은 되지만, 의도와 다르게 동작하는 것.
이렇한 에러를 대비하기 위해 자바에서는 실행시 발생 할 수 있는 프로그램 오류를 두가지로 분류한다
- 에러(Error) - 프로그램 코드에 의해서 수습이 안될경우.
- 예외(Exception) - 프로그램 코드에 의해서 수습될 수 있는 미약한 오류의 경우
클레스의 계층 구조는 다음과 같다.
이중에서 Exception은Exception class - 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
RuntimeException class - 프로그래머의 실수로 발생하는 예외
다음과 같은 구성으로 볼 수 있다.
IOException - 입출력 예외
ClassNotFoundException - class 찾을 수 없음
- tyy-catch 필수예외이다.
ArithmeticException - 산술계산 예외 ex) 5/0
ClassCastException - 형변환 예외
NullPoiterException - Null포인트인터 ex) String = null; str.length;
- tyy-catch 선택적
try{
//예외가 발생할 가능성이 있는 문장들 넣는다.
}catch (Exception1 e1) {
//Exception1 이 발생한 경우, 이를 처리하기위한 문장 작성
}catch (Exception2 e2) {
//Exception2 이 발생한 경우, 이를 처리하기위한 문장 작성
}catch (ExceptionN eN) {
//ExceptionN 이 발생한 경우, 이를 처리하기위한 문장 작성
}
예외가 발생하지 않으면 try-catch 전체를 빠져나가서 다음 문장을 실행한다.
printStackTrace() - 예외발생 당시의 호출스택(call Stack)에 있었던 메서드의 정보와 예외 메시지 출력
getMessage() - 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다.
try {
System.out.println(3);
System.out.println(0/0);
System.out.println(4);
}catch ( ArithmeticException ae) {
ae.printStackTrace();
System.out.println("예외 메시지 :" + ae.getMessage());
}
여러 catch블럭을 하나의 catch 블럭으로 합쳐서 사용하는 경우
try {
...
}catch( ExceptionA | ExceptionB e) {
e.printStackTrace();
}
주의
조상과 자손의 관계에 있다면 사용불가
여러 예외를 한번에 처리하기 때문에 실제로 어떤 예외가 발생한것인지 알기 어렵다.
연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음
Exception e = new Exception("고의로 발생시켰음");
키워드 throw를 이용해서 예외를 발생시킨다.
throw e;
위 두줄을 한줄로 작성하면
throw new Exception("고의로 발생시켰음");
예외의 처리하는 방법은 지금까지 배워온 try-catch문(직접처리)을 사용하는 것 외에, 예외를 메서드에 선언(던지기)하는 방법이 있다.
메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어주기만 하면 된다.
void method() throws Exception1,Exception2 ... ExceptionN {
//메서드 내용
}
예제
import java.io.*;
class Ex8_10 {
public static void main(String[] args) {
try {
File f = createFile(args[0]);
System.out.println( f,getName()+" 파일이 성공적으로 생성되었습니다." );
}catch ( Exception e ) {
System.out.println(e.getMessage()+"다시 입력해 주시기 바랍니다.");
}
}
static File createFile(String fileName) throws Exception {
if(fileName ==null || fileName.equals(""));
throws new Exception("파일이름이 유효하지 않습니다.");
File f = new File(fileName);
//File 객체의 createNewFile메서드를 이용해서 실제 파일을 반환한다.
f.createNewFile();
return f;
}
}
public static void main(String[] args){
try {
method1();
} catch ( Exception e) {
System.out.println("main 메서드에서의 예외가 처리되었습니다.");
}
}
static void method1() throws Exception {
try{
throw new Exception();
} catch(Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e;
}
} //end main method
}
결과
method1메서드에서 예외가 처리되었습니다.
main 메서드에서의 예외가 처리되었습니다.
결과와 같이 method1() 과 main메서드 양쪽의 catch 블럭이 모두 수행되었음을 알 수 있다.