ABCD

예외처리 본문

PROGRAMMING LANGUAGE/JAVA

예외처리

카메사마 2024. 6. 9. 16:37

🐢 에러(error): 시스템 레벨에서 발생하는 개발자가 해결하기 어려운 치명적인 오류이다.

🐢 예외(exception): 개발자가 해결할 수 있는 오류

    - 일반 예외 (검사형 예외, 컴파일 타임 예외)

    - 실행 예외 (비검사형 예외, 런타임 예외)

 

    - 예외는 java.lang 패키지의 Throwable 클래스의 자식 객체이다. (프로그램 실행 중 발생하는 일종의 이벤트)

 

🐢 일반 예외

    - 컴파일러는 일반 예외의 발생 가능성을 탐지하면 컴파일 오류를 발생시킨다.

    - 개발자는 예외 처리 코드를 반드시 추가해야 한다.

일반 예외 발생 이유
ClassNotFoundException 존재하지 않는 클래스를 사용하려고 할 때 발생
InterruptedException 인터럽트 되었을 때 발생
NoSuchFieldException 클래스가 명시한 필드를 포함하지 않을 때 발생
NoSuchMethodException 클래스가 명시한 메서드를 포함하지 않을 때 발생
IOException 데이터 읽기 같은 입출력 문제가 있을 때 발생

 

🐢 실행 예외

    - 실행 예외는 컴파일러가 예외 처리 여부를 확인하지 못한다. (예외가 런타임, 즉 실행 중에 발생하므로 컴파일 타임 때는 모른다.)

    --> 프로그램 실행 시점의 데이터에 의존적인 논리적 오류이기 때문이다.

    --> 예외가 발생하면 JVM은 해당하는 실행 예외 객체를 생성한다.

실행 예외 발생 이유
ArithmeticException 0으로 나누기와 같은 부적절한 산술 연산을 수행할 때 발생
IllegalArgumentException 메서드에 부적절한 인수를 전달할 때 발생
IndexOutOfBoundsException 배열, 벡터 등에서 범위를 벗어난 인덱스를 사용할 때 발생
NoSuchElementException 요구한 원소가 없을 때 발생
NullPointerException null 값을 가진 참조 변수에 접근할 때 발생
NumberFormatException 숫자로 바꿀 수 없는 문자열을 숫자로 변환하려 할 때 발생

 

🐢 예외 처리 방법

    1. 예외 잡아 처리하기 (try-catch)

    2. 예외 떠넘기기 (thows)

 

🐢 try-catch

try{
	// 예외 발생 코드
}
catch(예외클래스1 참조변수){핸들러;}
catch(예외클래스2 | 예외클래스3 참조변수){핸들러;}	// 다수의 예외를 한꺼번에 잡으려면 | 연산자로 연결

// 여러 개의 catch 블럭이 있을 수 있다.
// 예외가 발생하면 예외 객체를 catch 블럭의 참조 변수로 전달한다.

finally{
	// 예외 발생 여부와 관계 없이 수행
}

! catch 블럭의 순서 중요하다. --> 우선순위에 해당한다.

 

🐢 Throwable 클래스의 주요 메서드

메서드 설명
public String getMessage() Throwable 객체의 자세한 메세지 반환
public String toString() Throwable 객체의 간단한 메세지를 반환
public void printStackTrace() Throwable 객체와 추적 정보를 콘솔 뷰에 출력

 

🐢 throws: 메서드에서 발생한 예외를 내부에서 처리하기가 부담스러울 때 throws 키워드를 사용하여 예외를 상위 코드 블럭으로 양도할 수 있다.

    - 예외를 1개 이상 선언할 수 있다.

 

🐢 자바 API 문서

    - 많은 메서드가 예외를 발생시키고 상위 코드로 예외 처리를 떠넘긴다.

    - 예외처리를 상위코드 블럭 한 곳에서 할 수 있다.


// 예시1

package main;

import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) {
		String s = "Time is money";
		StringTokenizer st = new StringTokenizer(s);

		while (st.hasMoreTokens()) {
			System.out.print(st.nextToken() + "+");
		}
		System.out.print(st.nextToken());
	}
}
// 예시2

package main;

public class Main {
	public static void main(String[] args) {
		int[] array = { 0, 1, 2 };

		System.out.println(array[3]);
	}
}
// 예시3

package main;

public class Main {
	public static void main(String[] args) {
		Thread.sleep(100);
	}
}
// 예시4

package main;

public class Main {
	public static void main(String[] args) {
		int[] array = { 0, 1, 2 };
		try {
			System.out.println("마지막 원소 => " + array[3]);
			System.out.println("첫 번째 원소 => " + array[0]);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("원소가 존재하지 않습니다.");
		}
		System.out.println("어이쿠!!!");
	}
}
// 예시5

package main;

public class Main {
	public static void main(String[] args) {
		int dividend = 10;
		try {
			int divisor = Integer.parseInt(args[0]);
			System.out.println(dividend / divisor);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("원소가 존재하지 않습니다.");
		} catch (NumberFormatException e) {
			System.out.println("숫자가 아닙니다.");
		} catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		} finally {
			System.out.println("항상 실행됩니다.");
		}
		System.out.println("종료.");
	}
}
// 예시6

package main;

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		try {
			square(in.nextLine());
		} catch (NumberFormatException e) {
			System.out.println("정수가 아닙니다.");
		}
	}

	private static void square(String s) throws NumberFormatException {
		int n = Integer.parseInt(s);
		System.out.println(n * n);
	}
}

'PROGRAMMING LANGUAGE > JAVA' 카테고리의 다른 글

패키지와 API 문서  (0) 2024.09.07
열거 타입  (0) 2024.06.10
인터페이스  (0) 2024.06.09
상속과 추상 클래스  (0) 2024.06.09