카테고리 없음

[자바의 다양한 기능들] 6-1. 예외처리하기와 미루기(1)

코딩펭귄 2024. 1. 9. 18:25

try-catch 문

  • try 블록 : 예외가 발생할 가능성이 있는 코드를 작성,  try 블록 안에서 예외가 발생하는 경우 : catch 블록이 수행
try{
   예외가 발생할 수 있는 코드 부분   
} catch(처리할 예외타입 e) {
   try블록 안에서 예외가 발생했을때 예외를 처리하는 부분
}

 

프로그래머가 예외를 처리해줘야 하는 예 (배열의 오류 처리)

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()); 
            //Index 5 out of bounds for length 5
            
			System.out.println(e.toString()); 
            // java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5

			System.out.println("비정상 종료되지 않았습니다.");
	}
}

// 출력결과
1
2
3
4
5
Index 5 out of bounds for length 5
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 (에러 풀네임 & 메시지)
비정상 종료되지 않았습니다.

 

 

try-catch-finally 문

  • finally 블럭에서 파일를 닫거나 네트웍을 닫는 등의 리소스 해제 구현을 함
  • finally의 역할 :오픈된, 사용한 리소스를 해제하는 역할
  • try{} 블럭이 수행되는 경우, finally{} 블럭은 항상, 무조건 수행 됨(return이 있어도 수행됨)
  • 여러 개의 예외 블럭이 있는 경우 각각에서 리소스를 해제하지 않고 finally 블록에서 해제하도록 구현함
  • 시스템 리소스를 오픈하고 쓰게되면, 클로즈를 해야되는데 클로즈를 안해줬을 경우!
  • 컴파일러에 의해 예외가 처리 되는 예 (파일 에러 처리)
  • 아래의 메인코드에서 만약 예외를 thorws 던지면, vm으로 가고, 비정상종료됨
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 e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
//			e.printStackTrace(); // 에러가 어디서났는지 딱 찝어줌
			System.out.println(e);
			try {
				fis.close();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		System.out.println("end");
	}
}

이렇게 여러개의 catch문을 사용하며 매번 close() 해주지 말고, 아래코드와 같이 finally에서 작성한다

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) {
//			e.printStackTrace(); // 에러가 어디서났는지 딱 찝어줌
			System.out.println(e);
		} finally {
			if(fis != null) { //열렸을때 close 해야하므로
			try {
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}
			System.out.println("finally");
		}
		System.out.println("end");
	}
}

단, try블록과 catch 블록에서 return문 사용해주더라도, finally블록은 항상 실행되므로 "finally" 는 항상 출력됨 (try가 불리면 finally는 항상 호출됨)

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

 

 

try-with-resources문

  • 리소스를 사용하는 경우(사용하고 나면) close() 하지 않아도 자동으로 해제 되도록 함
  • 자바 7부터 제공되는 구문
  • 처음엔, 리소스를 try() 내부에서 선언해야만 했음
  • close()를 명시적으로 호출하지 않아도 try{}블록에서 열린 리소스는 정상적인 경우나 예외가 발생한 경우 모두 자동으로 해제됨
  • 해당 리소스 클래스가 AutoCloseable 인터페이스를 구현 해야 함
  • FileInputStream의 경우에는 AutoCloseable을 구현하고 있음
  • 자바 9 부터 리소스는 try() 외부에서 선언하고 변수만을 try(obj) 와 같이 사용할 수 있음
public class FileExceptionHandling {

	public static void main(String[] args) {
//		FileInputStream fis = null;
		
		// 이렇게 try()내부에서 선언하면 close도 처리가 됨 
		try (FileInputStream fis = new FileInputStream("a.txt")) {
			System.out.println("read");
		} catch (FileNotFoundException e) { // file이 없을 경우 나는 exception
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) { // close 할때 나는 exception
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		System.out.println("end");
	}
}

 

 

AutoCloseable인터페이스 구현 실습

public class AutoCloseableObj implements AutoCloseable{

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

}
public class AutoCloseTest {

	public static void main(String[] args) {
		AutoCloseableObj obj = new AutoCloseableObj();
		
		try(obj){
			// 이 수행이 끝나면 AutoCloseableableObj 가 불리고, auto close가 됨
			throw new Exception(); //Exception 강제로 발생시킴
		}catch(Exception e) {
			System.out.println("exception");
		}
		
		System.out.println("end"); //closing...이 잘 불리는지 확인
	}

}
- 출력결과 -
closing...
exception
end