경주장
9주차 과제: 예외 처리 #9 자바에서 예외 처리 방법 (~03.09) 본문
✔️ 학습할 것 (필수)
+ 예외란?
자바에서 예외 처리 방법 (try, catch, throw, throws, finally)- 자바가 제공하는 예외 계층 구조
- Exception과 Error의 차이는?
- RuntimeException과 RE가 아닌 것의 차이는?
- 커스텀한 예외 만드는 방법
자바에서 예외 처리 방법
// Note: This class will not compile yet.
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class ListOfNumbers {
private List<Integer> list;
private static final int SIZE = 10;
public ListOfNumbers () {
list = new ArrayList<Integer>(SIZE);
for (int i = 0; i < SIZE; i++) {
list.add(new Integer(i));
}
}
public void writeList() {
// The FileWriter constructor throws IOException, which must be caught.
PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < SIZE; i++) {
// The get(int) method throws IndexOutOfBoundsException, which must be caught.
out.println("Value at: " + i + " = " + list.get(i));
}
out.close();
}
}
위의 코드는 컴파일 되지 않습니다. 그이유는 FileWirter가 던지는 Checked Eception인 IOException을 처리하지 않았기 때문입니다. 그대로 컴파일 하게 되면 아래와 같은 컴파일 에러가 발생합니다.
java: unreported exception java.io.IOException; must be caught or declared to be thrown
예외 처리에 관한 지식이 없으면 간단한 파일 읽기 쓰기 프로그램 조차 컴파일 할 수 없습니다. 자바에서 예외처리 방법을 배워봅시다!
try, catch, finally 등의 키워드를 통해 예외를 처리하는 방법을 알아보겠습니다.
Exception Handler를 만드는 가장 첫번째 step은 try 블럭을 작성하는 것입니다.
try {
code
}
catch and finally blocks ...
try 블락의 코드에는 예외가 발생할 수 있는 코드를 작성합니다.
위의 FileWriter 생성자 예시에서 컴파일 에러를 없애는 방법 중 하나는 FileWriter의 생성자 부분을 try 구문에 넣는 것입니다.
가장 단순한 방식은 아래와 같습니다.
public void writeList() {
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter("OutFile.txt"));
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
out.close();
}
예외가 발생할 수 있는 line을 try 블럭에 넣었고 컴파일 에러를 해결하였습니다. 하지만 위 코드는 여전히 문제가 있습니다. FileWriter 생성에 IOException이 생겨 예외가 발생하였다면 PrintWriter인 out은 초기화 되지 않습니다. 따라서 예외처리 구문 아래 for-loop에서 NullPointException이 발생합니다.
이를 해결한 코드는 아래와 같습니다.
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entered try statement");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
}
catch and finally blocks . . .
}
out의 생성과 그를 활용한 코드인 for-loop 구문까지 모두 try-block에 넣음으로써 NullPointException의 위험을 없앴습니다.
try-block에 해당되는 Exception Handler는 catch-block을 통해 만들 수 있습니다. catch-block은 try-block 바로 뒤에 작성하며 여러개 작성 될 수 있습니다.
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
ExceptionType은 Throwable 클래스를 상속받은 클래스여야 하며 Exception Handler인 catch block 내부에서는 try 구문에서 던진 ExceptionType 예외를 name이름으로 사용할 수 있습니다.
여러개의 예외에 대해서 같은 방식의 예외처리를 제공하고 싶은 경우 multi 캐치 문법을 적용할 수 있습니다.
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
finally 블럭은 try 블럭이 있다면 항상 실행됩니다. finally 블럭은 예외가 catch 블럭에 의해서 잡히든 말든 심지어 try나 catch 블럭에서 return, continue, break등의 분기문으로 블럭을 탈출하더라도 실행됩니다. 이런 특징 때문에 finally 블럭은 주로 clean-up code/ resource close등에 활용됩니다. resource close의 용도로 finally구문을 활용한다면 try-with-resource 문법을 활용하는 것이 좋습니다.
try-with-resource
자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원이 많습니다. InputStream, OutputStream, java.sql.Connection 등이 있습니다.
try-with-resource 문법은 자원의 close를 무조건적인 호출을 기존의 try-finally에 비해 간단한 문법으로 제공합니다.
InputStream과 FileStream을 동시에 활용하는 copy 메소드를 두 방식으로 작성하면 아래와 같습니다.
static void copy1(String src, String dst) throws IOException {
InputStream in = new FileInputStream(src);
try{
OutputStream out = new FileOutputStream(dst);
try{
byte[] buf = new byte[BUFFER_SIZE];
int n;
while((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
out.close();
}
} finally {
in.close();
}
}
static void copy2(String src, String dst) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
copy1에 비해 copy2는 코드가 더 짧고 분명해집니다.
@출처)
그리고
Effective Java 3/e 아이템 9 - try-finally 보다는 try-with-resource를 사용하라
'JAVA > whiteship_live-study' 카테고리의 다른 글
9주차 과제: 예외 처리 #9 커스텀한 예외 만드는법 (~03.09) (0) | 2022.03.03 |
---|---|
9주차 과제: 예외 처리 #9 자바의 예외 클래스들 (~03.09) (0) | 2022.03.03 |
9주차 과제: 예외 처리 #9 예외란 (~03.09) (0) | 2022.03.02 |
8주차 과제: 인터페이스 #8 상속, Default Method (~03.04) (0) | 2022.02.28 |
8주차 과제: 인터페이스 #8 (~03.04) (0) | 2022.02.25 |