
프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것, 프로그램 에러라고도 함
소스 코드 수정으로 해결 가능한 에러를 예외(Exception)라고 하는데
이러한 예외 상황(예측 가능한 에러) 구문을 처리 하는 방법인 예외 처리를 통해 해결
Java API Document에서 해당 클래스에 대한 생성자나 메소드를 검색하면
그 메소드가 어떤 Exception을 발생시킬 가능성이 있는지 확인 가능.
-> 발생하는 예외를 미리 확인하여 상황에 따른 예외 처리 코드를 작성할 수 있음

Exception과 Error 클래스 모두 Object 클래스의 자손이며 모든 예외의 최고 조상은 Exception 클래스
반드시 예외 처리해야 하는 Checked Exception과 해주지 않아도 되는 Unchecked Exception으로 나뉨

Unchecked Exception으로 주로 프로그래머의 부주의로 인한 오류인 경우가 많기 때문에
예외 처리보다는 코드를 수정해야 하는 경우가 많음



메소드 선언 시 throws Exception명을 추가하여 호출한 상위 메소드에게 처리 위임
계속 위임하면 main() 메소드까지 위임하게 되고
main() 메소드에서도 처리되지 않는 경우 프로그램이 비정상 종료됨.

오버라이딩 시 throws하는 Exception의 개수와 상관없이 처리 범위가 같거나 후손 이어야 함

Java API에서 제공하는 Exception Class 만으로는 처리할 수 없는 예외가 있을 경우
사용자의 필요에 의해 생성하는 Exception Class.
Exception 발생하는 곳에서 throw new 예외클래스명()으로 발생

package edu.kh.exception.test;
import java.util.Scanner;
public class ExceptionTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
/*
while(true) {
System.out.println("정수 입력(0 입력시 종료) : ");
int input = sc.nextInt();
// 컴파일 에러 => 개발자가 코드 잘못쓴 것.
// 자료형이 맞지않아 연산을 못해서 "컴파일 에러"가 발생(코드 틀림)
//int a = 99.9;
int a = (int)99.9; // 코드로 수정 가능!
if(input == 0) {
break;
}
}
*/
// 런타임 에러 예제
// 런타임 에러 : 프로그램 수행 중 발생하는 에러
// 주로 if문으로 처리가 가능하다.
int[] arr = new int[3]; // 길이 3 : 인덱스 0, 1, 2 까지
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
//arr[3] = 40; 프로그램 실행 시 에러
//java.lang.ArrayIndexOutOfBoundsException : 배열 범위 초과 예외
if( 3 >= arr.length ) { // 배열 인덱스 범위 초과 시
System.out.println("배열 범위를 초과했습니다.");
} else {
arr[3] = 40;
}
}
}
package edu.kh.exception.model.service;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionService {
// 예외(Exception) : 소스 코드의 수정으로 해결 가능한 오류
// 예외는 두 종류로 구분됨
// 1) Unchecked Exception : 선택적으로 예외 처리
// 2) Checked Exception : 필수적으로 예외 처리
private Scanner sc = new Scanner(System.in);
public void ex1() {
System.out.println("두 정수를 입력받아 나누기한 몫을 출력");
System.out.print("정수 1 입력 : ");
int input1 = sc.nextInt();
System.out.print("정수 2 입력 : ");
int input2 = sc.nextInt();
try {
System.out.println("결과 : " + input1 / input2);
// ArithmeticException : 산술적예외 0으로 나눌 수 없다.
} catch(ArithmeticException e) {
// try 에서 던져진 예외를 catch문 매개변수 e로 잡음.
System.out.println("infinity"); // 처리 코드
}
if(input2 !=0) {
System.out.println("결과 : " + input1 / input2);
} else {
System.out.println("infinity"); //
}
// 발생하는 예외 중 일부 예외는 try-catch 구문 사용 안해도
// 예외 상황을 방지할 수 있다!
// 일부예외 == 대부분 UncheckedException
}
public void ex2() {
// 여러가지 예외에 대한 처리 방법
try {
System.out.println("입력 1 : ");
int num1 = sc.nextInt(); // java.util.InputMismatchException
System.out.println("입력 2 : ");
int num2 = sc.nextInt(); // java.util.InputMismatchException
System.out.println("결과 : " + num1 / num2); // ArithmeticException
String str = null;
System.out.println( str.charAt(0) );
// java.lang.NullPointerException : 참조하지 않는 참조변수를 이용해서 코드 수행 시 발생
} catch(InputMismatchException e) {
System.out.println("타입에 맞는 값만 넣어주세요");
} catch(ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
} catch(Exception e) { // 하나로 퉁치기 가능
System.out.println("뭔지 모르겠으나 예외가 발생해서 처리함.");
}
// 예외처리 + 다형성
// Exception 클래스 : 모든 예외의 최상위 부모
// 다형성 - 업캐스팅 : 부모타입 참조변수로 자식객체를 참조.
// ** 상위 타입의 예외 클래스를 catch문에 작성하면
// 다형성 업캐스팅에 의해 모두 잡아서 처리 가능!! **
}
public void ex3() {
// 1) try - catch - finally
// finally : try 구문에서 예외가 발생 하든 말든 무조건 마지막에 수행
try {
System.out.println( 4 / 0 );
}catch(ArithmeticException e) {
System.out.println("예외처리됨");
// 2) catch문 매개변수 활용
// 매개변수 e : 예외 관련된 정보 + 예외 관련 기능
System.out.println( e.getClass() ); // 어떤 예외 클래스인가?
// class java.lang.ArithmeticException
System.out.println( e.getMessage() ); // 예외 발생시 출력된 내용
// / by zero
System.out.println( e ); // e.toString();
// java.lang.ArithmeticException: / by zero
e.printStackTrace(); // 에러 발자취 찾기
} finally {
System.out.println("무조건 수행 됨");
}
}
public void ex4() {
// throws : 호출한 메서드에게 예외를 던짐
// -> 호출한 메서드에게 예외를 처리하라고 위임하는 행위
// throw : 예외 강제 발생 구문
try {
methodA();
} catch(Exception e) {
// Exception : 모든 예외의 최상위 부모
// Exception이 catch 매개변수로 작성되었다.
// == 예외 종류 상관없이 모두 처리
e.printStackTrace();
// 발생한 예외가 메서드와 위치에 대한 모든 내용을 출력
// 예외 발생 지점 추적
}
}
public void methodA() throws IOException{
methodB();
}
public void methodB() throws IOException{
methodC();
}
public void methodC() throws IOException{
// 예외 강제 발생 구문
throw new IOException();
}
}