- 프로그램 오류
- 예외 확인
- 예외 클래스 계층 구조
- Unchecked Exception
- 사용자 정의 예외
- 예외 처리 방법
- Exception 과 오버라이딩
프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것으로 프로그램 에러라고도 한다.
프로그램의 실행을 막는 소스 코드상의 문법 에러로 소스 코드 수정으로 해결한다.
System.out.println 을 out.println 으로 작성하는 등
프로그램 실행 중 발생하는 에러로 주로 if 문 사용으로 에러를 처리한다. 배열의 인덱스 범위를 벗어났거나 계산식의 오류 등에서 발생한다.
if (num2 == 0) { 에러 처리 코드 }
컴퓨터 오작동으로 인한 에러로 소스 코드 수정으로 해결이 불가능하다.
인터넷 연결 불량 등
소스 코드 수정으로 해결 할 수 있는 예측 가능한 에러를 예외 Exception 라고 하는데 이러한 예외 상황 구문을 처리 하는 방법인 예외 처리를 통해 해결한다.
Java API Document 에서 해당 클래스에 대한 생성자나 메소드를 검색하면 그 메소드가 어떤 Exception 을 발생시킬 가능성이 있는지 확인 가능하다.
발생하는 예외를 미리 확인하여 상황에 따른 예외 처리 코드를 작성할 수 있다.
// java.io.BufferedReader 중 readLine() 메소드
// 키보드 입력을 효율적으로 읽어오는 객체로 Scanner 보다 기능은 부족하지만 속도가 빠름
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public String readLine() throws IOException
Java 프로그램 실행 중 예를 들어 산술적 Exception 상황이 발생하면 해당 상황과 일치하는 예외 클래스 ArithmeticException 을 찾아서 new ArithmeticException 객체로 만들어 문제가 발생한 위치로 던진다.
Exception 과 Error 클래스 모두 Object 클래스의 자손이며 모든 예외의 최고 조상은 Exception 클래스이다.
Exception 은 반드시 예외 처리해야 하는 Checked Exception 과 해주지 않아도 되는 Unchecked Exception 으로 나뉜다.
Throwable : 던져질 수 있는 클래스의 공통점을 묶어 놓은 인터페이스
Error : 개발자가 코드로 예상할 수 없는 심각한 에러
Exception : 개발자가 코드로 예상할 수 있는 미약한 에러
RuntimeException
if 문으로 해결 가능한 Unchecked Exception 으로 가벼운 문제이므로 컴파일 단계에서 예외가 발생하지 않는다.
// ArithmeticException
5 / 0
// IndexOutOfBoundsException
int[] a = new int[3];
int[5];
// NullPointerException
Car c = NULL;
c.getWheel()
Exception
if 문으로 해결 불가능한 Checked Exception 으로 IOException 등 컴파일 단계에서 예외가 발생한다.
RuntimeException 클래스
Unchecked Exception 이며 주로 프로그래머의 부주의로 인한 오류인 경우가 많으므로 예외 처리보다는 코드를 수정해야 하는 경우가 많다.
RuntimeException 후손 클래스
ArithmeticException
0 으로 나누는 경우 발생하며 if 문으로 나누는 수가 0 인지 검사
NullPointerException
Null 인 참조 변수로 객체 멤버 참조 시도 시 발생하며 객체 사용 전에 참조 변수가 null 인지 확인
NegativeArraySizeException
배열 크기를 음수로 지정한 경우 발생하며 배열 크기를 0 보다 크게 지정해야 함
ArrayIndexOutOfBoundsException
배열의 index 범위를 넘어서 참조하는 경우 배열명의 length 를 사용하여 배열의 범위 확인
ClassCastException
객체의 형변환 시 객체 타입 변환이 적절하지 않을 시 발생하며 instanceof 연산자로 객체타입 확인 후 cast 연산
InputMismatchException
Scanner 를 사용하여 데이터 입력 시 입력 받는 자료형이 불일치할 경우 발생
Java API 에서 제공하는 Exception 클래스만으로는 처리할 수 없는 예외가 있을 경우 사용자의 필요에 의해 생성하는 Exception 클래스이다.
Exception 발생하는 곳에서 throw new 예외클래스명 ( ) 으로 발생시킨다.
public class UserException extends Exception {
// 기본 생성자
public UserException("입력한 점수 범위 초과") { }
// 매개변수 생성자
public UserException(String msg) { super(msg); }
}
public class UserExceptionController {
public void method() throws UserException {
throw new UserException("사용자 정의 예외 발생");
}
}
public class Run {
public static void main(String[] args) {
UserExceptionController uc = new UserExceptionController();
try {
uc.method();
} catch (UserException e) {
System.out.println(e.getMessage()); // 설정한 에러 메세지 출력
}
}
}
이미 존재하는 자바의 Exception Class 중 하나를 상속 받아서 관련성 있는 예외가 있으면 해당 예외 클래스를 없으면 Exception 또는 RuntimeException 을 상속 받는다.
Checked Exception 을 원할 경우 Exception 상속
Unchecked Exception 을 원할 경우 RuntimeException 상속
System.exit();
만나면 무조건 종료되며 자원 해제 역할// 1) try catch 예외 처리
public void method() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("입력 : ");
String str = br.readLine();
System.out.println("입력된 문자열 : " + str);
} catch (IOException e) {
e.printStackTrace();
}
}
// 2) try catch finally 예외 처리
public void method() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("입력 : ");
String str = br.readLine();
System.out.println("입력된 문자열 : " + str);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
System.out.println("BufferedReader 반환");
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
상위 타입 예외를 매개변수로 작성하면 하위 타입의 예외를 모두 처리가 가능하다.
이 때 상위 타입 catch 를 뒤쪽에 배치해서 하위 타입 catch 에 대한 검사가 먼저 진행되게 해야 오류가 발생하지 않는다.
계속 위임하면 main ( ) 메소드까지 위임하게 되고 main ( ) 메소드에서도 처리되지 않는 경우 프로그램이 비정상 종료된다.
public static void main(String[] args) {
ThrowsTest tt = new ThrowsTest();
try {
tt.methodA(); // 최종적으로 IOException 받음
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("프로그램 종료");
}
}
// throws 예외 처리
public void methodA() throws IOException {
methodB();
}
public void methodB() throws IOException {
methodC();
}
// methodC 에서 IOException 발생 시 호출한 곳으로 던지겠다는 의미
public void methodC() throws IOException {
throw new IOException(); // IOException 강제 발생
}
오버라이딩 시 throws 하는 Exception 의 개수와 상관없이 처리 범위가 같거나 후손이어야 한다.
즉 Exception 클래스는 상속이 될 수록 상위 클래스보다 예외의 내용이 더 상세하게 기술된다.
public class Parent {
public void method() throws IOException { }
}
public class Child1 extends Parent {
@Override
public void method() throws EOFException { } // Exception 사용 시 부모이므로 오류
}
상위 클래스로부터 상속 받은 메서드를 하위 클래스에서 재정의 하는 것