혼자 공부하는 자바 📖/Chapter 10 예외 처리
Chapter 10-1. 예외 클래스
코이_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 연산자로 타입 체크를 하는 것이 좋다