1. 예외(Exception)
1️⃣ 예외란?
프로그램 실행 중 발생하는 비정상적인 상황을 의미
int a = 10 /0; // 실행 중 오류 발생➡️ 이런 실행 중(Runtime) 문제가 발생하면, 자바는 Exception 객체를 생성하고 프로그램에 알림
✔️ 예외를 처리하지 않으면 프로그램은 즉시 종료
2️⃣ 예외의 종류
1) Checked Exception
- 통제는 불가능하지만 예상은 가능한 예외
- 컴파일러가 예외 처리를 강제로 요구 → 처리하지 않으면 컴파일 오류 발생
- Try/Catch문으로 예외를 잡거나 예외가 터진 메서드를 호출한 곳으로 throw할 수 있음
But, 예외가 JVM까지 넘어가기 전에는 처리해야 함
- Object > Throwable > Exception 클래스 안에서
RuntimException을 제외한 모든 Exception 클래스는 Checked Exception(예상 가능한 예외)
- 클래스명 extends Exception 으로 사용 가능
2) Unchecked Exception (Runtime Exception)
- 예상이 불가능하며 실행 중 발생하는 예외
- 처리 강제 없음
- 한 번 예외가 터지고 나면 이제 예상 가능한 예외이기 때문에 조치해야 함
- Object > Throwable > Exception 중
RuntimException 클래스는 Unchecked Exception(예상 불가능한 예외)
- 클래스명 extends RuntimException 으로 사용 가능
3) Error (아직 안 배움)
- 프로그램이 복구 불가능한 심각한 오류
→ 일반적으로 예외 처리로 다루지 않음
3️⃣ 자바 예외 계층 구조

2. 예외 전파(Exception Propagation)
1️⃣ 예외 전파란?
예외가 발생하면 그 메서드 안에서 해결되지 않을 경우, 그 예외는 메서드를 호출한 곳으로 전달되면서 위로 올라감
예외는 catch로 잡히지 않으면 자동으로 메서드 밖으로 튀어나가서 그 메서드를 호출한 쪽으로 전달
※ 예외가 발생하면 JVM까지 전달되기 전에 잡아채서(catch) 제어해야 함
2️⃣ 예외 전파의 예시
A() → B() → C()
- C() 안에서 예외가 발생
- C() 안에 try-catch 없음
- 그럼 예외는 C() 밖으로 나가서 B()에게 전달
- B()에도 try-catch가 없음
- 예외는 다시 B() 밖으로 나가서 A()로 전달
- A()에도 try-catch가 없음
- main에도 try-catch가 없으면 마지막으로 main을 호출한 JVM까지 전달됨 → 프로그램 종료(예외 메시지 출력)
3. 예외 처리(Exception Handling)
교재 p.351-358 / 8.10 예외 처리란?
1️⃣ 예외 처리란?
프로그램 실행 중 발생할 수 있는 오류(예외)를 미리 대비하고 처리하는 방법
오류 때문에 프로그램이 갑자기 종료되지 않도록 하고, 상황에 맞는 조치를 취하도록 도와줌
2️⃣ 예외 처리가 필요한 이유
프로그램에는 예측하기 어려운 상황이 많이 생김
- 존재하지 않는 파일을 읽으려고 할 때
- 0으로 나누기를 할 때
- 네트워크 연결이 끊겼을 때
- 사용자가 잘못된 입력을 했을 때
이런 상황이 발생하면 프로그램은 오류를 내고 멈추지만, 예외처리를 사용하면 멈추지 않고 다른 동작을 하도록 만들 수 있음
3️⃣ 예외 처리 문법
1) try–catch
try {
// 예외가 발생할 수 있는 코드
} catch (예외타입 e) {
// 해당 예외가 발생했을 때 실행되는 코드
}① 0으로 나누기
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
}② 여러 예외 처리
try {
int[] arr = {1, 2};
System.out.println(arr[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("배열 인덱스가 잘못되었습니다.");
} catch (Exception e) {
System.out.println("알 수 없는 오류 발생");
}
3) throws 키워드
메서드에서 예외를 직접 처리하지 않고 호출한 곳으로 예외를 떠넘기는 것
public void readFile() throws IOException {
FileReader fr = new FileReader("test.txt");
}호출하는 쪽에서 다시 try-catch 해야 함.
4️⃣ 교재 예제
예제 8-2. 배열 인덱스 예외 처리 (p.355)
package ex08;
public class ArrayError {
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5 };
int i = 0;
for (i = 0; i <= array.length; i++) {
System.out.println(array[i] + " ");
}
}
}
package ex08;
public class ArrayError {
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5 };
int i = 0;
try {
for (i = 0; i <= array.length; i++) {
System.out.println(array[i] + " ");
}
} catch (Exception e) {
System.out.println("인덱스 " + i + "는 사용할 수 없네요!");
}
}
}
예제 8-3. 입력 예외 처리 (p.356)
package ex08;
public class ExceptionTest3 {
public static void main(String[] args) {
int num = Integer.parseInt("ABC");
System.out.println(num);
}
}|
package ex08;
public class ExceptionTest3 {
public static void main(String[] args) {
try {
int num = Integer.parseInt("ABC");
System.out.println(num);
} catch (NumberFormatException e) {
System.out.println("NumberFormat 예외 발생");
}
}
}
4. 실습
package ex08;
public class Try01 {
public static void main(String[] args) {
throw new RuntimeException("강제로 예외를 터트림");
}
}
package ex08;
public class Try02 {
static void start(){
throw new RuntimeException("예외가 발생함");
}
public static void main(String[] args) {
try {
start();
} catch (RuntimeException e){
System.out.println("괜찮아");
}
}
}
package ex08;
class Service{
static void loginProcess(String username, String password){
if (username.length() < 5){
throw new RuntimeException("username의 길이가 짧아요");
}
if (!password.equals("1234")){
throw new RuntimeException("password가 틀렸어요");
}
}
}
// SRP 잘못된 처리를 하는 곳
class Controller{
static void login(String username, String password){
try {
Service.loginProcess(username, password);
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
}
public class Try03 {
public static void main(String[] args) {
Controller.login("ssar","1234");
}
}
package ex08.ch01;
/**
* checked exception
* unChecked exception
*/
public class CheckTry {
static void m1() throws Exception {
throw new Exception("강제로 던진 Checked Exception");
}
static void m2(){
throw new RuntimeException("강제로 던진 Unchecked Exception");
}
public static void main(String[] args) {
try {
m1();
} catch (Exception e) {
System.out.println(e.getMessage());
}
m2();
}
}
package ex08.ch01;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class CheckTry02 {
// 예상 불가능한 익셉션 코드 (RuntimeException 관련 자식들)
static void m1(int n) {
try {
int result = 10 / n;
System.out.println(result);
} catch (RuntimeException e) {
System.out.println("0");
}
}
// 예상 가능한 익셉션 코드 (RuntimeException이 아닌 모든 것 / Exception)
static void m2() {
try {
FileInputStream fis = new FileInputStream("파일명");
} catch (FileNotFoundException e) {
System.out.println("파일명 못찾았어!! 다시 시도해!!");
}
}
public static void main(String[] args) {
m1(0);
m2();
}
}
필기 정리

※ if vs RuntimeException?

Share article