프로그램 오류
1. 컴파일 에러: 컴파일 시에 발생하는 에러 (오타, 구문, 자료형 오류 체크)
2. 런타임 에러: 실행 시에 발생하는 에러
3. 논리적 에러: 실행은 되지만, 의도와 다르게 동작하는 것
예외 클래스의 계층구조
자바에서는 실행 시 발생할 수 있는 오류를 클래스로 정의하였다.
Exception클래스를 더 자세히 보면 다음과 같다.
-Exception클래스: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외
-RuntimeException클래스: 프로그래머의 실수로 발생하는 예외
try-catch문
프로그램 실행시 발생할 수 있는 예외에 대하여 프로그래머가 미리 예외처리를 하여
실행 중인 프로그램의 갑작스러운 비정상 종료를 막고, 정상적인 실행상태를 유지할 수 있도록 하는 것이다.
try-catch문의 구조는 다음과 같다.
try{
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
// Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} catch (Exception2 e2) {
// Exception2가 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
}
다음 예시를 보면 이중구문이 가능함을 알 수 있다.
class ExceptionEx1 {
public static void main(String[] args)
{
try {
try { } catch (Exception e) { }
} catch (Exception e) {
try { } catch (Exception e) { } // 에러. 변수 e가 중복 선언되었다.
} // try-catch의 끝
try {
} catch (Exception e) {
} // try-catch의 끝
} // main메서드의 끝
}
다음은 산술연산과정에서 오류가 있을 때 발생하는 예외인 ArithmeticException에 대한 예시이다.
class ExceptionEx3 {
public static void main(String args[]) {
int number = 100;
int result = 0;
for(int i=0; i < 10; i++) {
try {
result = number / (int)(Math.random() * 10);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("0");
} // try-catch의 끝
} // for의 끝
}
}
멀티 catch블럭
try {
...
} catch (ExceptionA | ExceptionB e) {
e.printStackTrace();
}
이와같이 '|'기호를 이용하여 여러 catch블럭을 하나의 catch블럭으로 합칠 수 있다.
finally블럭
예외의 발생여부에 관계없이 실행되어야할 코드를 포함시킬 목적으로 사용한다.
try{
// 예외가 발생할 가능성이 있는 문장들을 넣는다.
} catch (Exception1 e1) {
// Exception1이 발생했을 경우, 이를 처리하기 위한 문장을 적는다.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 문장들을 넣는다.
// finally블럭은 try-catch문의 맨 마지막에 위치해야한다.
}
예외가 발생하면 'try -> catch -> finally' 순으로 실행되고
예외가 발생하지 않으면 'try -> finally' 순으로 실행된다.
자동 자원 반환 (try-with-resources문)
try-catch문의 변형인 try-with-resources문은 입출력과 관련된 클래스를 사용할 때 유용하다.
class TryWithResourceEx {
public static void main(String args[]) {
try (CloseableResource cr = new CloseableResource()) {
cr.exceptionWork(false); // 예외가 발생하지 않는다.
} catch(WorkException e) {
e.printStackTrace();
} catch(CloseException e) {
e.printStackTrace();
}
System.out.println();
try (CloseableResource cr = new CloseableResource()) {
cr.exceptionWork(true); // 예외가 발생한다.
} catch(WorkException e) {
e.printStackTrace();
} catch(CloseException e) {
e.printStackTrace();
}
} // main의 끝
}
class CloseableResource implements AutoCloseable {
public void exceptionWork(boolean exception) throws WorkException {
System.out.println("exceptionWork("+exception+")가 호출됨");
if(exception)
throw new WorkException("WorkException 발생!!!");
}
public void close() throws CloseException {
System.out.println("close()가 호출됨");
throw new CloseException("CloseException발생!!!");
}
}
class WorkException extends Exception {
WorkException(String msg) { super(msg); }
}
class CloseException extends Exception {
CloseException(String msg) { super(msg); }
}
예외 되던지기(exception re-throwing)
예외를 처리한 후에 인위적으로 다시 발생시키는 구문이다.
이는 try-catch문을 사용해서 예외를 처리해주고 catch문에서 필요한 작업을 행하고
throw문을 사용해서 예외를 다시 발생시키는 과정을 통해 작업한다.
재발생한 예외는 위 메서드를 호출한 메서드에게 전달되고 호출한 메서드의 try-catch문에서 예외를 또다시 처리한다.
이 방법은 하나의 예외에 대해서 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해야 할 작업이 있을때
사용하는 방법이다.
class ExceptionEx17 {
public static void main(String[] args)
{
try {
method1();
} catch (Exception e) {
System.out.println("main메서드에서 예외가 처리되었습니다.");
}
} // main메서드의 끝
static void method1() throws Exception {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("method1메서드에서 예외가 처리되었습니다.");
throw e; // 다시 예외를 발생시킨다.
}
} // method1메서드의 끝
}
이런식으로 이용할 수 있다.
'Sketch (Programming Language) > Java' 카테고리의 다른 글
Java의 정석 Chapter 10. 날짜와 시간 & 형식화 date, time and formatting, Chapter 11. 컬렉션 프레임웍 (0) | 2022.05.22 |
---|---|
Java의 정석 Chapter 9. java.lang패키지와 유용한 클래스 (0) | 2022.05.21 |
Java의 정석 Chapter 6, 7. 객체지향 프로그래밍 (0) | 2022.05.15 |
Java의 정석 Chapter 5. 배열 (0) | 2022.05.14 |
Java의 정석 Chapter 4. 조건문과 반복문 (0) | 2022.05.13 |