1️⃣ 프로그램 오류
- 컴파일 에러 : 컴파일 시에 발생하는 에러
- 런타임 에러 : 실행 시에 발생하는 에러
- 논리적 에러 : 실행은 되지만, 의도와는 다르게 동작하는 것
- 에러(error) : 프로그램 코드에 의해서 수습될 수 없는 심각한 오류 (스택오버플로, 메모리부족)
- 예외(exception) : 프로그램 코드에 의해서 수습될 수 있는 다소 미약한 오류
2️⃣ 예외 클래스 계층 구조
Checked Exception
- 컴파일러가 예외처리를 확인하는 Exception 클래스
- 컴파일 단계에서 발생
- 무조건 예외처리 해야된다
- 예외 발생 트랜잭션 처리 시 롤백은 하지 않아도 됨
Unchecked Exception (런타임 익셉션)
- 컴파일러가 예외처리를 확인하지 않는 Exception 클래스
- 런타임 단계에서 발생
- 반드시 예외처리를 해야 되는 것은 아님
- 예외 발생 트랜잭션 처리 시 롤백을 해야한다
3️⃣ try - catch
발생한 예외를 처리하지 못하면, 프로그램은 비정상적으로 종료되며, 처리되지 못한 예외는 JVm의 예외처리기가 받아서 예외의 원인을 화면에 출력한다
public class ExceptionEx1 {
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(e.getMessage());
}
}
}
}

0으로 나누는 예외가 발생했을 때, 예외 메세지를 출력하고 다음 반복을 계속 수행합니다. try - catch 처리를 하지 않았다면 예외가 발생해서 프로그램이 비정상적으로 종료됨
4️⃣ 예외 발생과 catch블럭
public class ExceptionEx2 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
System.out.println(3);
System.out.println(0 / 0);
System.out.println(4); // 실행되지 않음
} catch(ArithmeticException ae) {
if(ae instanceof ArithmeticException)
System.out.println(true);
System.out.println("ArithmeticException");
} catch(Exception e) { // ArithmeticException을 제외한 모든 예외를 처리합니다
System.out.println("Exception");
}
System.out.println(6);
}
}
printStackTrace()와 getMessage()
예외가 발생했을 때 생성되는 예외 클래스의 인스턴스에는 발생한 예외에 대한 정보가 담겨 있으며, getMessage()와 printStackTrace()를 통해 이 정보들을 얻을 수 있음.

5️⃣ 예외 발생시키기
키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있음
new
를 이용해서 발생시키려는 예외 클래스의 객체를 만듬
2. 키워드 throw
를 이용해서 예외를 발생public class ExceptionEx3 {
public static void main(String[] args) {
try {
throw new Exception("고의 발생");
} catch(Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}

6️⃣ 메서드에 예외 선언하기
메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws
를 사용해서 메서드 내에서 발생할 수 있는 예외를 적어준다
사실 예외를 throws에 명시하는 것은 예외를 처리하는 것이 아니라 자신을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것. 예외를 전달받은 메서드가 또다시 자신을 호출한 메서드에게 전달할 수 있고, 이런 식으로 계속 호출스택에 있는 메서드들을 따라 전달되다가 제일 마지막에 있는 main메서드에서도 예외가 처리되지 않으면, main 메서드마저 종료되어 프로그램 전체가 종료됩니다.
public class ExceptionEx4 {
public static void main(String[] args) throws Exception {
method1();
}
static void method1() throws Exception {
method2();
}
static void method2() throws Exception {
throw new Exception();
}
}

예외가 발생한 메서드에서 예외처리를 하지 않고 자신을 호출한 메서드에게 예외를 넘겨줄 수는 있지만, 이것으로 예외가 처리된 것은 아니고 예외를 단순히 전달만 하는 것. 결국 어느 한 곳에서는 반드시 try-catch문으로 예외 처리를 해 주어야 함.
7️⃣ finally 블럭
try {
// 예외가 발생할 가능성이 있는 문장을 넣음
} catch(Exception e) {
// 예외 처리를 위한 문장을 넣음
} finally {
// 예외의 발생 여부와 관계없이 항상 수행되어야 하는 문장들을 넣음
// finally 블럭은 try-catch문의 맨 마지막에 위치해야 함
}
try 블럭에서 return문이 실행되는 경우라고 finally 블럭의 문장들이 먼저 실행된 후에, 현재 실행 중인 메서드를 종료합니다.
8️⃣ 사용자 정의 예외 만들기
기존의 정의된 예외 클래스 외에 필요에 따라 프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있습니다.
public class MyException extends Exception { // Exception or RuntimeException
MyException(String msg) {
super(msg);
}
}
Reference
자바의 정석(남궁성), 도우출판
Uploaded by Notion2Tistory v1.1.0