예외?
예외 클래스 구조
✅ NullPointerException
String data = null;
System.out.println(data.toString()); // NullPointerException 발생!
// 결과: "Exception in thread 'main' java.lang.NullPointerException..."
✅ ArrayIndexOutOfBoundsException
String[] arr = new String[3];
System.out.println(arr[3]); // 0~2까지가 유효 인덱스, 3은 범위 벗어남
또는, main args 길이 조건이 안 맞을 때.
if(args.length == 2) {
String data1 = args[0];
String data2 = args[1];
...
} else {
// args 인덱스 접근 불가.. -> ArrayIndexOutOfBoundsException
}
// 결과: "Exception in thread 'main' java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds..."
✅ NumberFormatException
String data1 = "100";
String data2 = "a100";
int value1 = Integer.parseInt(data1); // ok
int value2 = Integer.parseInt(data2); // NumberFormatException 발생!
결과: "Exception in thread 'main' java.lang.NumberFormatException: For input string: 'a100'..."
✅ ClassCastException
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
Dog dog = new Dog();
Cat cat = new Cat();
Dog d = (Dog) animal; // animal이 Cat 타입이면 ClassCastException 발생!
안전하게 캐스팅 하려면 instanceof로 타입 체크 후 처리해야 한다.
if(animal instanceof Dog) {
Dog d = (Dog) animal;
}
예외 처리의 목적
예외 처리의 기본 코드
try {
// 예외 발생 가능 코드
} catch(예외클래스 e) {
// 예외 발생 시 처리 코드
} finally {
// 무조건 실행 코드 (자원 해제, 로그 등)
}
public class TryCatchFinallyExample {
public static void main(String[] args) {
try {
Class clazz = Class.forName("java.lang.String2");
} catch(ClassNotFoundException e) {
System.out.println("클래스가 존재하지 않습니다.");
}
}
}
존재하지 않는 클래스명을 사용할 때 ClassNotFoundException 발생
public class TryCatchFinallyRuntimeExceptionExample {
public static void main(String[] args) {
String data1 = null, data2 = null;
try {
data1 = args[0]; data2 = args[1];
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("실행 매개값의 수가 부족합니다.");
return;
}
try {
int value1 = Integer.parseInt(data1);
int value2 = Integer.parseInt(data2);
int result = value1 + value2;
System.out.println(data1 + " + " + data2 + " = " + result);
} catch(NumberFormatException e) {
System.out.println("숫자로 변환할 수 없습니다.");
} finally {
System.out.println("다시 실행해보세요.");
}
}
}
🤔 언제 쓸까나..?
try {
// 코드
} catch(ArrayIndexOutOfBoundsException e) {
// 배열 인덱스 오류 처리
} catch(NumberFormatException e) {
// 숫자 변환 오류 처리
} finally {
// 자원 해제 등
}
리턴타입 메소드명(매개변수) throws 예외클래스1, 예외클래스2 { ... }
① 생성자의 메소드 선언 끝 부분에 사용되어 메소드 내에서 발생될 예외를 떠넘긴다.
② throws 뒤에는 메서가 한 예외를 지정(,로 구분해서) 기술한다.
③ 모든 예외를 넘기기 위해 간단하게 throws Exception으로 작성할 수 있다.
④ 새로운 예외 발생시키기 위해 사용한다.
✅ throws의 역할!!
➡️ "이 메소드를 호출하는 곳에서 이 예외를 처리해야 해!" 라고 미리 명시하는 역할
④번은 오답이다!
"새로운 예외를 발생시키기 위해서 사용한다"고 했는데,
새로운 예외를 발생시키려면 throw(throw new ...)를 사용하기!