[Java 기능] 예외 처리와 미루기

2022. 2. 15. 18:16·Java & Kotlin

try-catch문

try {
  /* 예외가 발생할 수 있는 코드 */
} catch(처리할 예외 타입 e) {
 /* try 블록 안에서 예외 발생 시 예외 처리 코드 */
}
  • catch문이 수행되면 이후 수행문 또한 실행됨 (시스템 종료 x)
  • catch문에서 로그를 남기는 것이 좋음

 

ArrayIndexException.java

배열의 인덱스 범위 초과 시 오류 처리 (runtime 오류)

package ch08;

public class ArrayIndexException {

	public static void main(String[] args) {
		
		int[] arr = {1,2,3,4,5};
		
		try {
			for( int i = 0; i <= 5 ; i ++ ) {	// 인덱스의 범위가 배열 크기 초과
				System.out.println(arr[i]);
			}
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println(e.getMessage());
			System.out.println(e.toString());	// Exception의 full name, message로 구성
		}
		
		System.out.println("here");	// 예외 처리 후에도 실행됨
	}	

}

 

수행 결과
1
2
3
4
5
Index 5 out of bounds for length 5
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
here

 

 

try-catch문을 사용하지 않는다면?

  • 에러 메세지가 출력되지만 에러 발생한 코드의 다음 코드는 실행되지 않고 시스템 종료됨

 


 

try-catch-finally문

  • finally 블럭 : 시스템 리소스(파일, 네트워크.. )를 사용한 후 해제(close) 해주는 역할
  • try 블럭이 수행되는 경우, finally 블럭은 항상 수행됨
  • 여러 개의 예외 블럭이 있는 경우 각각에서 리소스를 해제하지 않고 finally 블럭에서 해제

 

FileExceptionHandling.java (try-catch문으로만 구현)
  • FileInputStream을 이용하여 파일을 불러들이는 코드
  • 각 블럭에서 리소스를 해제(close)를 해주어야 하고, 해제할 때 try-catch 구문을 사용해야 함
  • 가독성 떨어짐
package ch08;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileExceptionHandling {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		try {
			fis = new FileInputStream("a.txt");
			System.out.println("read");
			try {
				fis.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			System.out.println(e);
		}
		System.out.println("end");
	}

}

 

FileExceptionHandling.java (finally 블럭 사용)
  • 각 블럭에서 리소스를 해제하는 것이 아닌 finally 블럭에서 리소스를 해제한다.
  • try 블럭이 실행되고 오류 발생 시 catch 블럭 안의 코드가 실행되고 finally 블럭의 코드 또한 실행된다.
package ch08;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileExceptionHandling {

	public static void main(String[] args) {
		
		FileInputStream fis = null;
		
		try {
			fis = new FileInputStream("a.txt");
			System.out.println("read");
			
		} catch (FileNotFoundException e) {
			System.out.println(e);
		} finally {
			if(fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println("finally");
		}
		
		System.out.println("end");
	}

}

 

수행 결과
java.io.FileNotFoundException: a.txt (지정된 파일을 찾을 수 없습니다)
finally
end

 


 

try-with-resources문

  • 자바 7부터 제공
  • 리소스를 사용하는 경우 close()를 명시적으로 호출하지 않아도 자동으로 해제되도록 함
  • 리소스는 try() 내부에서 선언해야 함
  • 해당 리소스 클래스가 AutoCloseable 인터페이스를 구현해야 함
  • FileInputStream의 경우 AutoCloseable을 구현하고 있음
  • 자바 9부터 리소스는 try() 외부에서 선언하고 변수만 입력해서 사용할 수 있음

 

AutoCloseableObj.java

AutoCloseable 인터페이스를 구현하는 클래스

package ch08;

public class AutoCloseableObj implements AutoCloseable{

	@Override
	public void close() throws Exception {
		
		System.out.println("closing..");
	}
	
}

 

AutoCloseTest.java
  • try() 문에 AutoCloseable을 구현한 클래스의 객체를 입력하면 close()를 명시하지 않아도 실행된다.
package ch08;

public class AutoCloseTest {

	public static void main(String[] args) {
		
		AutoCloseableObj obj = new AutoCloseableObj();
		
		try(obj) {	// try에 매개변수로 AutoCloseable을 구현한 클래스의 객체 입력
			throw new Exception(); // exception 강제 발생
			
		} catch(Exception e) {
			System.out.println("exception");
		}
		
		System.out.println("end");
	}

}

 

수행 결과
closing..
exception
end

 


 

예외 처리 미루기

  • 예외 처리는 예외가 발생하는 문장에서 처리하는 방법과 이를 사용하는 부분에서 처리하는 방법 두가지가 있음
  • throws를 이용하면 예외가 발생할 수 있는 부분을 사용하는 문장에서 예외를 처리할 수 있음
  • main 함수에서 throws시 시스템 aborted

 

ThrowsException.java
package ch08;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ThrowsException {
	
	public Class loadClass(String fileName, String className) throws ClassNotFoundException, FileNotFoundException {	// 예외 처리 미루기
		
		FileInputStream fis = new FileInputStream(fileName);
		Class c = Class.forName(className);
		return c;
	}

	public static void main(String[] args) {
		
		ThrowsException test = new ThrowsException();
		try {	// 메서드를 사용하는 쪽에서 예외처리
			test.loadClass("a.txt", "abc");
		} catch (ClassNotFoundException e) {
			System.out.println(e);
		} catch (FileNotFoundException e) {
			System.out.println(e);
		}
	}

}

 

수행 결과
java.io.FileNotFoundException: a.txt (지정된 파일을 찾을 수 없습니다)
  • a.txt 파일 존재하는 경우
java.lang.ClassNotFoundException: abc

 


 

하나의 try 블럭에서 예외가 여러개 발생하는 경우

  • 여러개의 예외가 발생하는 경우 예외를 묶어서 하나로 처리할 수 있음
try {
    test.loadClass("a.txt", "java.lang.String");
} catch (ClassNotFoundException | FileNotFoundException e) {	// try/multi-catch
    e.printStackTrace();
}
  • 각각의 예외를 따로 처리할 수 있음
  • 이때 Exception 클래스는 모든 예외 클래스의 최상위 클래스이며 따로 명시하지 않은 예외가 발생했을시 default 처리
  • Exception 블럭은 맨 마지막에 위치해야 함
try {
    test.loadClass("a.txt", "java.lang.String");
} catch (ClassNotFoundException e) {	// ClassNotFound 예외 처리
    e.printStackTrace();
} catch (FileNotFoundException e) {	// FileNotFoundException 예외 처리
    e.printStackTrace();
} catch (Exception e) {	// default 예외 처리
	e.printStackTrace();
}

 

저작자표시 비영리 변경금지 (새창열림)

'Java & Kotlin' 카테고리의 다른 글

[Java 기능] 사용자 정의 예외 클래스  (0) 2022.02.15
[Java 기능] 예외 처리의 개념과 필요성  (0) 2022.02.15
[Java 기능] 스트림 활용  (0) 2022.02.15
'Java & Kotlin' 카테고리의 다른 글
  • [Java 기능] 오류 로그 남기기 - java.util.logging.Logger 활용
  • [Java 기능] 사용자 정의 예외 클래스
  • [Java 기능] 예외 처리의 개념과 필요성
  • [Java 기능] 스트림 활용
Sue
Sue
개발 공부 로그
  • Sue
    Sue's devlog
    Sue
  • 전체
    오늘
    어제
    • 분류 전체보기 (122)
      • Algorithm (2)
      • WEB (8)
      • Java & Kotlin (83)
      • Spring (26)
      • Database (1)
      • Infra (0)
      • Git (1)
      • devlog (1)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Sue
[Java 기능] 예외 처리와 미루기
상단으로

티스토리툴바