예외 클래스
1.예외 종류
예외란 사용자의 잘못된 조작 및 개발자의 잘못된 코딩으로 발생하는 프로그램 오류를 말한다.
예외가 발생하면 프로그램은 바로 종료된다는 점이 에러와 비슷하다.
그러나 예외와 에러의 다른 점은 예외는 예외 처리 ( exception handling ) 을 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다.
예외에는 두 가지의 종류가 있다.
1. 일반 예외 ( Exception )
2. 실행 예외 ( Runtime Exception )
일반 예외는 프로그램 실행 시 예외가 발생할 가능성이 높기 때문에 자바 소스를 컴파일 하는 과정에서 해당 예외 처리 코드가 있는지 검사한다. 만약에 예외 처리 코드가 없다면 컴파일 오류가 발생한다.
실행 예외는 실행 시 예측할 수 없이 갑자기 발생하기 때문에 컴파일 하는 과정에서 예외 처리 코드가 있는지 검사하지 않는다.
자바에서는 예외를 클래스로 관리하는데 JVM 은 프로그램을 실행하는 도중 예외가 발생시 해당 예외 클래스로 객체를 생성하고 예외 객체를 이용할 수 있도록 해준다.
모든 예외 클래스는 다음과 같이 java.lang.Exception 클래스를 상속받는다.
보라색 java.lang.Exception 은 자바에서 예외처리를 할 수 있게 제공해주는 최상위 보무 클래스이며
하늘색 Exception들은 단순 Exception이다. 즉 컴파일 시 발생하는 Exception이다. (일반예외)
하지만 초록색 RuntimeException은 프로그램 실행시 발생하는 런타임 Exception이다. (실행예외)
쉽게 말해서..
일반 예외과 실행 예외 클래스는 RuntimeException 클래스를 기준으로 구별
- RuntimeException 하위 클래스가 아니면 일반 예외
- RuntimeException 하위 클래스면 실행 예외
2. 실행 예외
실행 예외는 자바 컴파일러가 체크하지 않기 때문에 오로지 개발자의 경험에 의해 예외 처리 코드를 작성해야한다.
만약 개발자가 실행 예외 처리 코드를 넣지 않을 경우에 프로그램은 바로 종료된다.
2-1. NullPointerException
public class Test01{
public static void main(String[] args) {
String data = null;
System.out.println(data.toString());
}
}
Exception in thread "main" java.lang.NullPointerException
at solution.Test01.main(Test01.java:9)
data의 변수는 null 값을 가지고 있기 때문에 String 객체를 참조하고 있지 않다.
하지만 String 객체의 toString() 메소드를 호출하기 때문에 NullPointerException 발생한다.
2-2. ArrayIndexOutOfBoundsException
배열에서 인덱스 범위를 초과할 경우 발생되는 실행 예외로서
public class Test01{
public static void main(String[] args) {
String data1 = args[0];
String data2 = args[1];
System.out.println(data1);
System.out.println(data2);
}
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 0 out of bounds for length 0
2개의 실행 매개값을 주지 않았기에 args[0], args[1]과 같이 인덱스를 사용할 수 없기에 에러가 발생한다.
2-3. NumberFormatException
public class Test01{
public static void main(String[] args) {
String data1 = "a200";
int value1 = Integer.parseInt(data1);
System.out.println(data1);
}
}
Exception in thread "main" java.lang.NumberFormatException: For input string: "a200"
int value1 = Integer.parseInt(data1);를 통해 문자열을 숫자로 변환하려고 했으나 숫자로 변환할 수 없는 값이 들어가 있으므로 NumberFormatException을 발생시킨다.
2-4. ClassCastException
타입 변환 Casting은 상위, 하위 클래스 간에 발생하기도 하고 구현 클래스와 인터페이스 간에도 발생한다.
이러한 관계가 아니라면 클래스는 다른 타입으로 변환할 수 없기 때문에 ClassCastException이 발생한다.
public class Test01{
public static void main(String[] args) {
Cat cat = new Cat();
changeDog(cat);
}
private static void changeDog(Animal animal) {
System.out.println(animal.getClass().getName());//Cat
// if(animal instanceof Dog) {
Dog dog = (Dog) animal;
// }
}
}
//부모
class Animal{}
//Animal을 상속받음 자식
class Dog extends Animal{}
class Cat extends Animal{}
Exception in thread "main" java.lang.ClassCastException: class solution.Cat cannot be cast to class solution.Dog (solution.Cat and solution.Dog are in unnamed module of loader 'app')
instanceof를 통해 매개변수로 받은 animal 이 Dog 타입으로 형변환이 가능한지 확인이 가능한다. 주석처리를 하지 않으면 ClassCastException이 발생하지 않으므로 주석처리를 했다.
Animal의 자식객체인 Cat으로 참조객체를 생성했으나 changeDog 매서드에서 다른 자식 타입인 Dog 타입으로 변환할 수 없기 때문에 에러가 발생했다.
그래서 가능하면 instanceof를 사용하여 타입 체크를 먼저 진행하는 것이 좋다.