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 |