사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말합니다. 예외가 발생하면 프로그램은 곧바로 종료가 됩니다. 하지만 예외 처리를 통해 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있습니다.
자바는 예외가 발생할 가능성이 높은 코드를 컴파일할 때 예외 처리 유무를 확인합니다.
예외에는 두가지 종류가 있습니다. 일반예외와, 실행예외입니다.
자바에서는 예외를 클래스로 관리합니다. JVM은 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성합니다.
그리고 예외 처리 코드에서 예외 객체를 이용할 수 있도록 해줍니다.
일반예외와 실행 예외 클래스는 RuntimeException을 기준으로 구별합니다.
RuntimeException의 하위 클래스가 아니면 일반예외 클래스이고, 상속관계에서 부노에 RuntimeException이 있으면 실행 예외 클래스입니다.
실행 예외는 자바 컴파일러가 체크하지 않기 때문에, 개발자가 예외 처리 코드를 직접 작성해야 합니다. 만약 개발자가 실행 예외 처리코드를 넣지 않았을 경우, 해당 예외가 발생하면 프로그램은 종료됩니다.
가장 빈번하게 발생하는 실행 예외입니다.
객체 참조가 없는 상태, 즉 null 값을 갖는 참조 변수로 객체 접근 연산자인 도트를 사용했을 때 발생합니다.
배열에서 인덱스 범위를 초과할 경우 발생합니다. 배열 항목을 지정한 범위를 초과할 때 발생하는 예외입니다.
프로그램을 개발하다 보면 문자열로 되어있는 데이터를 숫자로 변경하는 경우가 발생합니다. Integer, Double와 같은 Wrapper 클래스를 이용하여 문자열을 숫자로 변경할 때, 숫자로 변환할 수 없는 문자가 포함되어 있다면 예외를 발생시킵니다.
타입 변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생합니다. 이러한 관계가 아니라면 클래스는 다른 타입으로 변환할 수 없기 때문에 ClassCastException이 발생합니다.
아래와 같이 상속관계와 구현관계가 있습니다.
Animal animal = new Dog(); RemoteControl rc = new Television();
Cat cat = (Cat) animal; Audio audio = (Audio) rc;
하지만 위처럼 타입변환을 할때 대입된 객체가 아닌 다른 클래스 타입으로 변환하면 ClassCastException이 발생합니다.
이런 예외를 발생시키지 않으려면 타입 변환 전에 instanceof 연산자로 확인을 확인을 할 수 있습니다.
Animal animal = new Dog(); RemoteControl rc = new Television();
if(animal instanceof Cat){ if(rc instanceof Audio){
Cat cat = (Cat) animal Audio audio = (Audio) rc;
} }
try 블록 내부에는 다양한 예외가 발생할 수 있습니다. 이 경우에는 다중 catch 블럭을 이용해서 작성할 수 있습니다. catch 블럭을 여러개 만들어서 해당 타입의 예외가 발생할 경우 catch 블럭을 실행하도록 되어 있습니다.
만약 catch 블럭이 여러개라도 한개의 catch가 발생합니다. try 안에서 동시 다발적으로 예외가 발생하지 않고, 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문입니다.
다중 catch 블럭을 작성할 때는 상위 예외 클래스가 하위 예외 클래스보다 아래에 위치해야 합니다.
예외가 발생할 경우 처리해줄 예외를 catch블록 위에서부터 차례대로 검색하기 때문입니다.
경우에 따라서는 메소드를 호출한 곳으로 예외를 떠넘길 수도 있습니다. 이때 사용하는 키워드가 throws입니다. throws 키워드는 예외를 호출한 곳으로 떠넘기는 역할을 합니다. throws 키워드 뒤에는 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 됩니다.
리턴타입 메소드이름(매개 변수,) throws 예외클래스 1,2 ...{
}