예외(Exception)


예외란 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류를 말한다. 에러와 오류는 하기의 표와 같은 차이점과 공통점이 있다.

  에러(Error) 예외(Exception)
차이점 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것 프로그램 자체에서 오류가 발생하는 것
공통점 에러(Error)나 예외(Exception)가 발생하면 곧바로 프로그램이 종료됨

에러나 예외가 발생할 시 곧바로 프로그램이 종료되지만 예외 같은 경우는 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 할 수 있다. 또한 무슨 시스템이든 에러가 발생을 하여 불능이 되어 버리면 곤란한 상황을 야기하며 수많은 유저가 사용하는 시스템일 경우 불능이 되는 순간 큰 불이익을 가져올 수 있는 상황까지 이어져 버린다. 따라서 예외는 프로그램에서는 절대적으로 눈여겨봐야 할 부분이다.

 

예외(Exception)의 종류


예외에는 두 가지 종류가 있다. 하나는 일반 예외이고 다른 하나는 실행 예외이다. 간략하게 보면 일반 예외는 컴파일 시점에서 발생하는 예외를 말하며, 실행 예외는 프로그램 실행 시에 발생하는 예외를 말한다. 구체적으로 보면 하기 표와 같다.

일반 예외(Exception) 컴파일러 체크 예외라고도 하며, 프로그램 실행 시 예외가 발생할 가능성이 높기 때문에 자바 소스를 컴파일하는 과정에서 해당 예외 처리 코드가 있는지 검사하여 예외 처리 코드가 없다면 컴파일 오류가 발생한다.
실행 예외(Runtime Exception) 컴파일러 넌 체크 예외라고도 하며, 실행 시 예측할 수 없이 갑자기 발생하기 때문에 컴파일하는 과정에서 예외 처리 코드가 있는지 검사하지 않는다.

자바에서는 예외를 클래스로 관리를 한다. JVM에서는 프로그램을 실행하는 도중에 예외가 발생하면 해당 예외 클래스로 객체를 생성한다. 그리고 예외 처리 코드에서 생성된 예외 객체를 이용할 수 있도록 해준다. 모든 예외 클래스는 java.lang.Exception 클래스를 상속받는다.

 

위 그림과 같이 일반 예외와 실행 예외 클래스는 Runtime Exception 클래스를 기준으로 구별한다. Runtime Exception의 하위 클래스가 아니면 일반 예외 클래스이고 하위 클래스이면 실행 예외 클래스이다. JVM 역시 마찬가지로 Runtime Exception의 상속 여부로 일반 예외와 실행 예외를 판단하게 된다.

 

실행 예외


일반 예외의 경우에는 컴파일 시 검사하여 예외 처리 코드를 강제적으로 작성하게 한다. 하지만 실행 예외의 경우에는 실행하는 도중에 발생하는 예외 이기 때문에 예외 처리 코드의 강제성이 없어 오로지 개발자의 경험에 의해서만 예외 처리 코드를 작성해야 한다. 

 

○Null Pointer Exception

java.lang.NullPointerException은 자바 프로그램에서 가장 빈번하게 발생하는 실행 예외이다. 이것은 객체 참조가 없는 상태 즉 null 값을 참조 변수로 객체 접근 연산자인 도트(.)를 사용했을 때 발생한다. 객체가 없는 상태에서 객체를 사용하려 하여 발생한 예외이다.

public class NullPointerException {
	public static void main(String[] args) {
    	String data = null;
        System.out.println(data.toString[]);//예외 발생
        //data가 null값이므로 String 객체를 참고하고 있지 않는 상황에서
        //String 객체의 toString()메소드를 호출하였기에 NullPointerException이 발생
     }
}

 

 

○ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException은 배열에서 인덱스 범위를 초과할 경우 발생하는 실행 예외이다. 

public class ArrayIndexOutOfBounds {
	public static void main(String[] args) {
    	String[] arr = new String[2];
        arr[0] = "data1";
        arr[1] = "data2";

		System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);//예외 발생
        //arr배열의 인덱스를 2개까지만 선언하였지만 3번째 인덱스를 사용하려고 하여 ArrayIndexOfBounds예외가 발생
     }
}

 

○NumberFormatException

개발을 하다 보면 문자열로 되어 있는 데이터를 숫자로 변경하는 경우가 자주 발생한다. 대표적으로 Wrapper 클래스인 Integer의 parseInt(String s) 메소드를 사용하여 문자열을 숫자로 변환하지만 숫자로 변환될 수 없는 문자가 포함되어 있는 경우 java.lang.NumberFormatException을 발생시킨다.

public class NumberFormatException {
	public static void main(String[] args) {
    	String data = "data";
        int value = Integer.parseInt(data);//예외 발생
        //data라는 문자열은 숫자로 변화할 수 없기 때문에 NumberFormatException이 발생
       }
}

 

○ClassCastException

타입 변환은 상위 클래스와 하위 클래스 간(상속)에 발생하고 구현 클래스와 인터페이스 간(구현)에도 발생한다. 이러한 상속 관계 또는 구현 관계가 아닌 경우에 타입 변환을 시도할 경우 타입 변환를 할 수 없기 때문에 ClassCastException이 발생한다.

public class ClassCastException {
	public static void main(String[] args) {
    	Dog dog = new Dog();//Dog클래스는 Animal클래스를 상속함
        changeAnimal(dog);
        
        Apple apple = new Apple();//Apple클래스는 Fruits클래스를 상속함
        changeAnimal(apple);
    }
    
    public static void changeAnimal(Object obj) {
    	Animal animal = (Animal)obj;//에러 발생
        //dog객체는 Animal 클래스를 상속하여 만들어진 객체 이므로 타입 변환이 가능하지만
        //apple객체의 경우는 Fruits 클래스를 상속하여 만들어진 객체 이므로 타입 변환이 불가능하여
        //ClassCastException이 발생
    }
}

'JAVA' 카테고리의 다른 글

람다식(Lambda Expression)  (0) 2022.07.17
enum  (0) 2022.01.16
JAVA 실행과정 & JVM  (0) 2022.01.09
예외 처리  (0) 2022.01.05
final & static  (0) 2021.12.31

+ Recent posts