본문 바로가기
JAVA

[JAVA] 자바의 예외 처리(try-catch) 정리

by IT 정복가 2023. 8. 28.
728x90

예외

  • 에러: 컴퓨터 하드웨어의 고장으로 인해 응용프로그램 실행 오류가 발생하는 것으로, 개발자는 이런 에러에 대처할 방법이 없다.
  • 예외: 잘못된 사용 또는 코딩으로 인한 오류를 말한다. 예외 처리를 통해 계속 실행 상태를 유지할 수 있다.
예외의 종류

일반 예외(Exception): 컴파일러가 예외 처리 코드 여부를 검사하는 예외

실행 예외(Runtime Exception): 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외

http://www.tcpschool.com/java/java_exception_class


예외 처리 코드

예외 처리 코드란?

- 예외가 발생했을 때 프로그램의 갑작스러운 종료를 막고 정상 실행을 유지할 수 있도록 처리하는 코드로

try-catch-finally로 구성된다.

 

try-catch-finally 블록은 생성자 내부와 메소드 내부에서 작성된다.

 

https://imasoftwareengineer.tistory.com/86

 

try{

	//예외 발생 가능 코드
    
}catch(예외클래스 e){

	//예외 처리
    
} finally{

	//항상 실행
    
}

try 블록 정상 실행: catch 블록 실행 X, finally 블록 실행 O

try 블록 예외 발생: catch 블록 실행 O, finally 블록 실행 O

(예외와 상관없이 finally 블록은 항상 실행된다. 또한 finally 블록은 생략이 가능하다.)

 

코드를 통해 확인해보자.

public class ExceptionHandlingExample {

	public static void printLength(String data) {
		int result = data.length();
		System.out.println("문자 수: "+result);
	}
	public static void main(String[] args) {
		printLength("Thisisjava");
		printLength(null); //매개값으로 null 대입
	}

}

메인 클래스의 printLength("Thisisjava"); 부분은 잘 실행되지만

null 값을 대입한 printLength(null); 부분에서 예외가 발생한다.

NullPointerException은 참조 변수가 null인 상태에서 필드나 메소드에 접근할 경우 발생한다.

 

이 코드에 예외 처리를 해보자.

public class ExceptionHandlingExample {

	public static void printLength(String data) {
		try {
			int result = data.length();
			System.out.println("문자 수: " + result);
		} catch (NullPointerException e) {
			System.out.println(e.getMessage());
		}
		//finally 생략
	}

	public static void main(String[] args) {
		printLength("Thisisjava");
		printLength(null); // 매개값으로 null 대입
	}

}

위 코드는 try 블록에서 NullPointerException 예외가 발생하면 catch 블록을 실행해서 예외를 처리하도록 하는 코드이다.

 

*예외의 정보를 출력하는 방법 3가지

e.getMessage() : 예외가 발생한 이유만 리턴

e.toString() : 예외의 종류도 리턴

e.printStackTrace() : 예외가 어디서 발생했는지 추적한 내용까지 출력

 


예외 종류에 따른 처리

try 블록에는 다양한 종류의 예외가 발생할 수 있다. 

이 경우, 다중 catch를 사용하면 예외에 따라 예외 처리 코드를 다르게 작성할 수 있다.

 

catch 블록이 여러 개라 할지라도 catch 블록은 단 하나만 실행된다.

그 이유는 하나의 예외가 발생하면 즉시 실행을 멈추고 해당 catch 블록으로 이동하기 때문이다.

 

예제를 통해 확인해보자.

public class ExceptionHandlingExample {

	public static void main(String[] args) {
		String[] array = {"100","1oo"};
		
		for(int i = 0; i <= array.length; i++) {
			try {
				int value = Integer.parseInt(array[i]);
				System.out.println("array["+i+"]: "+value);
			}catch(ArrayIndexOutOfBoundsException e) {
				System.out.println("배열 인덱스가 초과 됨: "+e.getMessage());
			}catch(NumberFormatException e){
				System.out.println("숫자로 변환할 수 없음: "+e.getMessage());
			}
		}
	}

}


예외 떠넘기기 (throws)

메소드 내부에서 예외가 발생할 때 try-catch 블록으로 예외를 처리하는게 기본이지만

메소드를 호출한 곳으로 예외를 떠넘길 수도 있다.

 

이때 사용하는 키워드가 throws이다. 

throws는 메소드 선언부 끝에 작성하는데, 떠넘길 예외 클래스를 쉼표로 구분해서 나열해주면 된다.

 

리턴타입 메소드명(매개변수, ...) throws 예외클래스1, 예외클래스2, ...{

}

throws 키워드가 붙어 있는 메소드에서 해당 예외를 처리하지 않고 떠넘겼기 때문에 

이 메소드를 호출하는 곳에서 예외를 받아 처리해야 한다.

 

예를 들어 아래의 코드는 ClassNotFoundException 을 throws하는 method2()의 예외를

method1()에서 호출할 때 처리하고 있다.

	public void method1() {
		try {
			method2();
		}catch(ClassNotFoundException e) {
			System.out.println("예외처리: "+ e.getMessage());
		}
	}
	
	public void method2() throws ClassNotFoundException {
		Class.forName("java.lang.String2");
	}

 

나열해야 할 예외 클래스가 많을 경우 throws Exception 또는 throws Throwable 만으로

모든 예외를 간단히 떠넘길 수도 있다.

public class ThrowsExample {

	public static void main(String[] args) throws Exception {
		findClass();
	}

	public static void findClass() throws ClassNotFoundException{
		Class.forName("java.lang.String2");
	}
}

 

728x90