프로그램 실행 중에 발생하여 프로그램 명령의 정상적인 흐름을 방해하는 이벤트
- 메소드 내에서 오류가 발생하면 메소드는 객체를 생성하고 이를 런타임 시스템에 전달한다
===> 예외 개체에는 오류가 발생한 당시의 프로그램 상태, 유형을 포함한 오류에 대한 정보를 담고 있다
try : exception에 대한 handler(catch)를 제공해야 한다
throws : exception을 던질 수 있는 메서드라는 것을 명시하는 구문
1. 오류 처리 코드를 일반 코드와 분리할 수 있다
2. 호출 스택 위로 오류를 전파할 수 있다
3. 오류 유형을 그룹화하고 구별할 수 있다
잘 작성된 애플리케이션이 예상하고 복구해야 하는 예외
Error, RuntimeException과 그 서브 클래스를 제외한 모든 Exception
ex) java.io.FileNotFoundException
애플리케이션 외부에 있는 예외적인 조건, 애플리케이션이 예상하거나 복구할 수 없는 예외
오류는 Catch 또는 Specific Requirement(획득 또는 지정 요구사항)의 적용을 받지 않음
Error와 그 하위 클래스
ex) java.io.IOError
애플리케이션 내부에 있는 예외적인 조건, 애플리케이션이 예상하거나 복구할 수 없음
논리 오류나 API의 부적절한 사용과 같은 프로그래밍 버그
예외 발생을 야기한 버그를 제거해야 함
ex) NullPointerException
try-with-resources 문은 Closeable과 같은 리소스(ex Stream)를 사용하는 상황에 적합함
// 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();
}
}
IOException 과 IndexOutOfBoundsException이 처리되어야 한다
1. 예외를 발생시킬 수 있는 (1)각 코드 줄을 try 블록 내에 배치하고 (2) 각각에 대해 별도의 exception handler를 제공한다
private List<Integer> list;
private static final int SIZE = 10;
public void writeList() {
PrintWriter out = null;
try { //하나의 try block
System.out.println("Entered try statement");
FileWriter f = new FileWriter("OutFile.txt"); // IOException
out = new PrintWriter(f);
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i)); // IndexOutOfBoundsException
}
}
catch and finally blocks . . .
}
try {
} catch (IndexOutOfBoundsException e) {
System.err.println("IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
}
Java SE 7 이상에서는 단일 catch 블록이 두 가지 이상의 예외 유형을 처리할 수 있음
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
예외가 발생해도 블록이 실행된다. 그래서 실수로 return, continue 에 의해 정리 코드를 우회하는 것을 방지할 수 있다.
위의 예제에서 3가지 방법 중 하나로 finally 블록이 종료될 수 있기 때문에 다소 복잡하다.
이렇게 3가지 방법 중 하나로 실행될 수 있기 때문에 다음과 같은 코드가 작성되어야 한다
finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
if (f != null) {
System.out.println("Closing FileWriter");
f.close();
}
}
try-with-resources 구문은 더 이상 필요하지 않은 시스템 리소스를 자동으로 release한다
public void writeList() throws IOException {
try (FileWriter f = new FileWriter("OutFile.txt");
PrintWriter out = new PrintWriter(f)) {
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
}
}
구문의 끝에서 resource가 닫히는 것이 보장된다
java.lang.AutoCloseable이나 java.io.Closeable을 구현하는 Object는 resource로 사용될 수 있다
Java SE 7이후에는 FileReader, BufferedReader 가 java.lang.AutoCloseable을 구현한다.
그러므로, try-with-resources에 사용할 수 있고, try문이 정상적으로 완료되었는지 여부에 관계없이 resources는 닫히게 된다.
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
Java SE 7 이전에는 finally 블록에서 리소스를 닫도록 처리했다. 하지만, 리소스 누수가 있을 수 있다. 리소스의 close 메서드를 호출해서 운영체제에게 해제를 요청해야 한다. 하지만, GC가 리소스를 회수하기 전에 이 작업을 수행하지 못하면 리소스를 해제하는 데 필요한 정보가 손실된다.
- 리소스의 메서드는 생성 순서와 반대 순서로 호출된다.
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.US_ASCII;
java.nio.file.Path outputFilePath =
java.nio.file.Paths.get(outputFileName);
// Open zip file and create output file with
// try-with-resources statement
try (
java.util.zip.ZipFile zf =
new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer =
java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// Enumerate each entry
for (java.util.Enumeration entries =
zf.entries(); entries.hasMoreElements();) {
// Get the entry name and write it to the output file
String newLine = System.getProperty("line.separator");
String zipEntryName =
((java.util.zip.ZipEntry)entries.nextElement()).getName() +
newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
[Spring] Spring IoC Container, BeanScan, 생명주기, 스코프 (0) | 2024.11.20 |
---|---|
[자바] Collections API : TreeMap (0) | 2024.10.22 |
[Java] Java 메모리 구조, Reflection (0) | 2024.01.06 |
[자바] 이팩티브자바 : 2. 생성자에 매개변수가 많다면 빌더를 고려해라 (0) | 2023.10.17 |
[데이터베이스]JPQL : N + 1 문제, Fetch Join, 주의사항 (0) | 2023.07.11 |