코이_CO2 2022. 12. 17. 16:34

예외 클래스

 

에러(error)

  • 컴퓨터 하드웨어의 오동작 또는 고장으로 인해 응용프로그램 실행 오류가 발생하는 것

 

예외(exception)

  • 에러 이외에 프로그램 자체에서 발생하는 오류
  • 사용자의 잘못된 조작 또는 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류
  • 일반 예외, 실행 예외

예외 처리(exception handling)

  • 프로그램을 종료하지 않고 정상 실행 상태가 유지되도록 하는 것
  • 자바에선 예외 발생 가능성이 높은 코드 컴파일 시 예외 처리 유무를 확인하나 모든 예외를 확인하진 않음
    • 예외의 종류 숙지

예외와 예외 클래스

자바에서는 예외를 클래스로 관리

모든 예외 클래스는 java.lang.Exception 클래스를 상속

일반 예외와 실행 예외 클래스는 RuntimeException 클래스를 기준으로 구별

 

일반 예외

  • 컴파일러 체크 예외
  • 컴파일 과정에서 해당 예외 처리 코드가 있는지 검사(없다면 컴파일 오류 발생)
    • 프로그램 실행 시 예외 발생 가능성이 높기 때문
  • RuntimeException 하위 클래스가 아닌 경우 해당

실행 예외

  • 컴파일러 넌 체크 예외
  • 컴파일 과정에서 예외 처리 코드가 있는지 검사하지 않는다
    • 실행 시 예측할 수 없이 갑자기 발생하기 때문
  • RuntimeException 하위 클래스일 경우 해당


실행 예외

컴파일러가 체크하지 않기 때문에 오로지 개발자의 경험에 의해 예외 처리 코드를 작성

예외 처리 코드를 넣지 않았을 경우, 해당 예외 발생 시 프로그램 종료

아래는 실행 예외의 대표적인 예시


NullPointerException

  • 가장 빈번하게 발생하는 실행 예외
  • 객체 참조가 없는 상태인 null값을 갖는 참조 변수로 객체 접근 연산자인 도트(.)를 사용할 경우 발생
    • 객체가 없는 상태에서 객체를 사용하려 했기 때문
public class NullPointerExceptionExample {
	public static void main(Stirng[] args) {
    	String data = null;  // null값을 갖기 때문에 String 객체를 참조하지 않고 있음
        System.out.println(data.toString());  // String 객체의 toString()메소드 호출
    }
}
// NullPointerException 발생!
// 아래의 예외 메세지가 Console 뷰에 출력되며 프로그램은 종료된다.
실행 결과 : NullPointerException 발생
Exception in thread "main" java.lang.NullPointerException
    at NullPointerExceptionExample.main(NullPointerExceptionExample.java:6) // 6번째 코드에서 발생

ArrayIndexOutOfBoundsException

  • 배열에서 인덱스 범위를 초과할 경우 발생
  • int[]arr = new int[3] 배열을 선언하면, arr[0]~arr[2]를 사용 가능하나 arr[3]을 사용하면 인덱스 범위를 초과하여 해당 예외 발생
  • 아래 코드에서는 2개의 실행 매개값을 주지 않아서 해당 예외가 발생
    • 배열 값을 읽기 전에 배열의 길이를 조건문 등을 이용해 조사하면 해결할 수 있음
    • ->  if(args.length==2)
ublic class ArrayIndexOutOfBoundsExceptionExample{
	public static void main(String[] args) {
    	String data1 = args[0];
    	String data1 = args[1];  // ArrayIndexOutOfBoundsException이 발생
    
    	System.out.println(data1);
    	System.out.println(data2);
    }
  }

NumberFormatException

  • 문자열로 되어있는 데이터를 숫자로 변경하는 과정에서 숫자로 변환할 수 없는 문자가 포함되어 있을 경우 발생
  • 문자열로 되어있는 데이터를 숫자로 변경할 때 주로 사용하는 메소드
    • Integer.parseInt(String s) : 주어진 문자열을 정수로 변환해서 리턴
    • Double.parseDouble(String s) : 주어진 문자열을 실수로 변환해서 리턴
  • 위 메소드들은 매개값인 문자열이 숫자로 변환될 수 있다면 숫자를 리턴하고 숫자로 변환할 수 없는 문자가 포함되어 있을 경우 java.lang.NumberFormatException을 발생시킨다
public class NumberFormatExceptionExample {
	public static void main(String [] args) {
    	String data1 = "100";
        String data2 = "a100";
        
        int val1 = Integer.parsInt(data1);
        int val2 = Integer.parsInt(data2); // NumberFormatException 발생(a가 들어있음)
        
        int result = val1 + val2; 
        System.out.println(result);
        
    }
}

ClassCastException

  • 타입 변환 과정에 있어 관계에 따라 다른 타입으로 변환할 수 없을 경우 해당 예외 발생
    • 타입 변환은 상위 클래스와 하위 클래스 간에 발생하고 구현 클래스와 인터페이스 간에도 발생
    • 위와 같은 관계가 아닐 경우 클래스는 다른 타입으로 변환할 수 없기 때문에 예외가 발생하게 된다
  • 해당 예외를 발생시키지 않기 위해서 타입 변환 전에 변환이 가능한지 확인
    • instanceof 연산자 사용
    • 연산의 결과가 true이면 좌항 객체를 우항 타입으로 변환이 가능
public class ClassCastExceptionExample {
	public static void main(String [] args) {
        Dog dog = new dog();
        changedog(dog); 

        Cat cat = new Cat();
        changedog(cat); 

	}
   
   public static void changedog(Animal animal) {
       //if(animal instanceof dog){
       Dog dog = (Dog) animal; 		// ClassCastException 발생
     //}							// Cat 객체를 매개값으로 줘서 Dog 타입으로 변환할 수 없기 때문
	}
}
    
  
 class Animal {}
 class Dog extends Animal{}
 class Cat extends Animal{}
  • 위 코드에서 13, 15 라인의 주석을 풀어주어 instanceof 연산자로 타입 체크를 하는 것이 좋다