Programming 기초/Java

[Java] 예외

뭉제 2023. 4. 23. 13:24
목차
1. 오류와 예외
2. 예외 발생
3. 예외 처리
4. Exception 클래스
5. 변수 e

 

 

Error vs Exception


시스템이 동작하는 도중 예상치 못한 상황이 발생해 실행 중인 프로그램이 영향을 받는 것을 오류와 예외 2가지로 구분할 수 있다.

 

오류(error)

· 시스템에 비정상적인 상황이 생겼을 때 발생 

· 시스템 레벨에서 프로그램에 수습할 수 없는 심각한 문제를 야기해 실행 중인 프로그램을 종료시킨다.

· 개발자가 미리 예측해 처리 불가

 

예외(exception)

· 개발자가 구현한 로직이나 사용자에 의해 발생

· 실행 중인 프로그램을 비정상적으로 종료시킨다.

· 개발자가 미리 예측해 처리 가능 -> 상황에 맞는 예외 처리 

 

=> 예외가 발생하면 자바 플랫폼이 가장 먼저 인지하여, 응용 프로그램에게 전달

=> 응용 프로그램에 예외에 대한 대처 코드가 없다면, 강제 종료 

 

 

예외가 발생하는 이유


예외는 왜 발생할까?

프로그램이 실행하는 동안 개발자가 설계한 의도대로 운영되지 않았기 때문일 것이다.

 

[예시]

- 정수를 0으로 나누는 경우 

- 배열의 길이보다 큰 인덱스로 배열의 원소를 접근하는 경우

- 존재하지 않는 파일을 열려고 하는 경우

- 정수 입력을 기다리는 코드가 실행되고 있을 때, 사용자가 문자를 입력한 경우

 

 

public class ExceptionApp {
	public static void main(String[] args) {
		System.out.println(1);
		System.out.println(2/0); //ArithmeticException
		System.out.println(3);
	}
}

실행결과

· 숫자를 0으로 나누는 경우 예외로 처리

· 실행 중 발생한 예외의 종류가 ArithmeticException임을 알려준다.

 

 

예외 처리


예외가 발생한 뒤에도 작업을 실행하려면 어떻게 해야 할까?

try-catch 문을 이용하면 예외가 발생해도 끝까지 실행할 수 있다.

 

try-catch-finally 문
try{
	예외 발생 가능성이 있는 코드;
} catch(처리할 예외타입 선언) { //예외마다 하나씩 작성
	예외 처리 코드;
} finally { //생략 가능
	예외 발생 여부와 상관없이 무조건 실행되는 코드;
}

· try 문에서 예외가 발생하면 남은 코드를 실행하지 않고, 해당 예외 타입과 일치하는 catch 문 실행

** 다른 제어문과 달리 예외 처리문은 중괄호 생략 불가

 

 

자바에서는 Exception 클래스를 제공하여 예외를 처리할 수 있게 한다.

public class ExceptionApp {
	public static void main(String[] args) {
		System.out.println(1);
		try {
			System.out.println(2/0);
		}catch(ArithmeticException e) {
			System.out.println("잘못된 계산");
		}
		System.out.println(3);
	}
}

실행결과


public class ExceptionApp {
	public static void main(String[] args) {
		System.out.println(1);
		int[] scores= {10, 20, 50};
		try {
			System.out.println(2);
			System.out.println(scores[3]); //ArrayIndexOutOfBoundsException
			System.out.println(2/0); //ArithmeticException
		} catch(ArithmeticException e) {
			System.out.println("잘못된 계산");
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("없는 값");
		}
		System.out.println(3);
	}
}

실행결과

· 다수의 예외를 처리하는 경우, 여러 개의 catch 문을 연속적으로 작성 가능

· 예외가 발생하면 try 문과 가까운 catch 문부터 순회하면서 해당 예외와 타입이 일치하는 catch 문을 실행

   -> catch 문의 위치 중요

· 더 좁은 범위의 예외를 처리하는 catch 문을 먼저, 더 넓은 범위의 예외를 처리하는 catch 문을 나중에 명시

· 예외를 처리하면 마지막 숫자 3까지 출력하고 프로그램 종료

 

 

Exception 클래스


예외상황마다 개별적으로 취해야 할 작업이 없거나 어떤 예외가 나올지 예측할 수 없다면 어떻게 해야 할까?

-> Exception 클래스 이용

 

예외도 클래스로 구현되어 있다.

 

ex) ArithmeticException 클래스의 Java API 문서

· RuntimeException의 자식 클래스

· RuntimeException은 Exception 클래스의 자식 클래스 

-> 여러 예외가 존재해도 Exception 클래스를 이용해 포괄적인 처리 가능

 

public class ExceptionApp {
	public static void main(String[] args) {
		System.out.println(1);
		int[] scores= {10, 20, 50};
		try {
			System.out.println(2);
			System.out.println(scores[3]); //ArrayIndexOutOfBoundsException
			System.out.println(2/0); //ArithmeticException
		} catch(ArithmeticException e) {
			System.out.println("잘못된 계산");
		} catch(Exception e) {
			System.out.println("이상 발생");
		}
		System.out.println(3);
	}
}

실행결과

· try 문에서 발생한 ArrayIndexOutOfBoundsException은 catch 문을 순회

  -> Exception을 포괄적으로 잡는 catch 문 실행

 

 

catch 문의 변수 e


catch 문의 변수 e도 인스턴스인데 이를 이용해 무엇을 할 수 있을까?

 

catch 문의 변수 e

· 예외 클래스의 객체 

· 예외 발생 원인, 발생 위치 등에 대한 정보들이 들어있다.

   -> 프로그램의 어디서 왜 예외가 발생했는지 알 수 있다.

 

=> 예외가 발생하면 자바는 catch를 호출하면서 인자로 예외 클래스의 인스턴스를 전달

=> e를 통해 예외 클래스의 변수나 메소드를 호출 가능

 

getMessage 메소드를 이용하면 예외 상황에 대한 상세한 정보를 얻을 수 있다.

자세한 메소드의 종류는 Throwable 클래스의 설명서에서 확인할 수 있다.

https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#constructor.summary