프로그램 실행 중에 발생하여 프로그램 명령의 정상적인 흐름을 방해하는 이벤트
- 메소드 내에서 오류가 발생하면 메소드는 객체를 생성하고 이를 런타임 시스템에 전달한다
===> 예외 개체에는 오류가 발생한 당시의 프로그램 상태, 유형을 포함한 오류에 대한 정보를 담고 있다
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
Lesson: Exceptions (The Java™ Tutorials > Essential Java Classes)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
[자바] JVM 구조 (0) | 2025.03.27 |
---|---|
[자바] 추상 클래스와 인터페이스에 대해 설명해주세요 (0) | 2025.03.27 |
[자바] Collections API : TreeMap (0) | 2024.10.22 |
[Java] Reflection (0) | 2024.01.06 |
[자바] 이팩티브자바 : 2. 생성자에 매개변수가 많다면 빌더를 고려해라 (0) | 2023.10.17 |