1 Java 예외클래스 구조

Java 예외클래스의 최상위 → Object
모든 예외클래스 → Throwable 클래스 상속받음

1️⃣ Errors

  • 문제 발생 시, 복구 불가능 🚨

  • 어플리케이션 자동종료 (Error의 경우, 복구시도 자체를 ⛔️)

    • 메모리문제 (OutOfMemoryError)
    • 스택크기문제 (StackOverFlowError)

2️⃣ Exception

  • 모든 예외클래스들이 상속하는 클래스

  • RuntimeExceptions → UnCheckedException

  • OtherExceptions → CheckedException

3️⃣ Exception 종류

Exception의미
IllegalArgumentException적절하지 못한 인자를 메서드에 넘겨주었을 때
ArithmeticException산수문제 (0으로 나눌 때)
NullPointerExceptionNull 오브젝트로 접근했을 때
e.getClass()예외가 발생한 상위클래스 name 가져옴
e.getName()e(예외클래스 객체)의 상위클래스(예외클래스) name 가져옴
e.getMessage()예외발생 시, 예외메시지
printStackTrace()예외발생 당시의 호출스택에 있었던 메서드정보와 예외메시지 화면에 출력

2 예외처리 방법

1️⃣ 재시도 (Other_CheckedException)

📌 재시도 : 일정시간 대기 후, 로직을 다시 실행하는 방법

  • 최대로 시도할 횟수를 정함 → 최대 횟수를 채울 때까지 다시 반복

  • try-catch에서 예외처리를 하는것이 아님 ⛔️

  • try-catch → 최대 횟수 넘기면 ➡️ CheckedException 예외발생 ✅

@Test
public void 예외_재시도() {
	final int MAX_COUNT = 5;
	int tryCount = MAX_COUNT;

	while(tryCount < MAX_COUNT) {
		try {
			// 로직 실행
			return; // 성공적인 종료
		} catch(Exception e) {
			// 실패 -> 일정시간 대기
		} finally {
			// 자원해제
		}
	}
	throw new RunTimeException(); // 예외발생
}

2️⃣ 책임회피 (Other_CheckedException)

📌 책임회피 : 발생한 Exception 내가 처리 ❌ → 나를 호출한 쪽으로 책임회피

  • 나를 호출 한 쪽 : 내 메서드를 실행시킨 (상위)메서드

  • 명시적으로 메서드 명 옆에 throws 붙임

@Test
public void 책임_회피() throws FileNotFoundException {
	BufferedReader br = new BufferedReader(new FileReader("c:/out.txt"));
	// 파일 입출력 로직
}

3️⃣ 예외전환 (Runtime_UncheckedException)

📌 예외전환 : 예외 발생 시, 다른 예외를 던짐

책임회피와 다른점

  • 책임회피 : 내 예외를 그대로 다른쪽으로 던짐

  • 예외전환 : 내가 의도한 다른 예외를 다시 발생시킴 → 의도된 예외전환 ⭐️

@Test
public void 예외_전환() {
	if(/*로그인 시도 5회 실패*/) {
		throw new LoingFailedFiveTimeException();
	}
	// 로그인 로직
}

3 Unchecked Exception 🆚 Checked Exception

Unchecked Exception (Runtime)Checked Exception (Other)
클래스Runtime Exception 클래스 + 자손클래스Exception 클래스 자손 중,
Runtime Exception 제외한 모든클래스
확인시점실행단계컴파일단계
강제처리여부강제처리 ❌반드시 강제처리(예외처리) ✅
예외발생 시, 트랜잭션처리rollback ✅rollback ❌
대표예외NullPointException
IllegalArgumentException
IOException
SQLException

가장 큰 차이점 → 강제처리 해야하는가 ? / 아닌가 ?

📍 Checked Exception : throws 던지거나, try-catch 필수

📍 Unchecked Exception : 개발자 부주의코딩에 의해 발생하는 예외

4 Checked Exception 예외처리

@Test
public void IOException() {
	ObjectMapper objectMapper = new ObjectMapper();
    
    MemberVo member = new MemberVo();
    
    String memberJson = objectMapper.writeValueAsString(member);
}
  • ObjectMapper : 객체와 Json문자열을 상호변환해주는 기능의 객체

  • JsonProcessingException 처리하라는 경고 🚨

1️⃣ Throws 던지는방법

@Test
public void Throws던지기() throws JsonProcessingException {
	ObjectMapper objectMapper = new ObjectMapper();
    
    MemberVo member = new MemberVo();
    
    String memberJson = objectMapper.writeValueAsString(member);
}
  • Throws던지기() 메서드 → 호출한 쪽으로 예외처리를 위임함

  • 장점 : 해당메서드에 명시적처리 ❌, 코드에 예외처리가 없어 가독성이 좋음

  • 단점 : 연속적으로 메서드호출 → 책임회피가 늘어날수록 → 상위에 있는 메서드의 throws 코드가 지저분해지고 예외의 위치를 찾는게 어려워짐

2️⃣ Try-Catch 감싸는방법

@Test
public void Try-Catch감싸기() {
	ObjectMapper objectMapper = new ObjectMapper();
    
    MemberVo member = new MemberVo();
    
    try {
    	String memberJson = objectMapper.writeValueAsString(member);
    } catch (JsonProcessingException e) {
    	e.printStackTrace();
        throw new RuntimeException();
    }
}
  • 예외가 발생 → 해당부분을 try-catch로 감쌈 → 해당 메서드 내에서 예외를 처리함

  • 장점 : 예외처리를 책임지고 처리 → 예외 전파 ❌

  • 단점 : 모든 예외마다 try-catch 사용 → 코드가 많이 늘어나 가독성이 떨어짐


5 예외처리 실습

1️⃣ Try-Catch (Other.Checked_rollback ⛔️)

try {
	// 예외가 발생할 가능성이 있는 코드
} catch (Exception1 e1) {
	// Exception1이 발생했을 때, 이를 처리하기 위한 코드
} catch (Exception2 e2) {
	// Exception2가 발생했을 때, 이를 처리하기 위한 코드
}

📌 Try 블럭 → 여러개의 catch 블럭이 올 수 있음
📌 발생한 예외의 종류와 일치하는 단 한개의 catch 블록만 수행됨

  • Exception : 발생한 예외에 대한 예외클래스
  • e : 예외클래스의 객체를 가리키는 참조변수

실습1

public class ExceptionDemo {
 
    public static void main(String[] args) {
        try {
            // 1을 0으로 나눴으므로 예외가 발생한다.
            System.out.println(1 / 0);
        } catch (IllegalArgumentException e) {
            System.out.println(e.getClass().getName());
            System.out.println(e.getMessage());
        } catch (ArithmeticException e) { // catch문 실행
            System.out.println(e.getClass().getName());
            System.out.println(e.getMessage());
        } catch (NullPointerException e) {
            System.out.println(e.getClass().getName());
            System.out.println(e.getMessage());
        }
    }
}

ArithmeticException catch 실행됨

실습2

public class ExceptionDemo {
 
    public static void main(String[] args) {
        try {
            System.out.println(1 / 0); // 예외발생
        } catch (IllegalArgumentException | ArithmeticException e) {
				// 예외 클래스 2개를 or(|)로 연결, 인스턴스는 1개
            System.out.println(e.getMessage());
        }
    }
}

→ JDK 1.7부터 catch block 하나로 합칠 수 있음

2️⃣ Throw (Runtime.Unchecked_rollback ✅) ⭐️

public class ExceptionDemo {
	
    public static void main(String[] args) {
    	Scanner scanner = new Scanner(System.in);
        
        System.out.println("아이디를 입력하시오");
        String username = scanner.nextLine();
        
        try {
        	if (username.equals("바보")) {
            	throw new IllegalArgumentException("부적절한 이름입니다.");
            }
        } catch (IllegalArgumentException e) {
        	System.out.println(e.getMessage());
        }
    }
}

📌 유효성 검사 시, throw → 고의로 예외를 발생시킴

  • new : 예외클래스 생성
  • throw : 해당 예외 발생

3️⃣ Throws (Other.Checked_rollback ⛔️)

void method() throws Exception1, Exception2 ••• {
	// 메서드내용
}

📌 throws → 메서드에 예외를 선언함

  • 메서드선언부에 예외선언 → 어떤 예외를 처리해야하는지 알 수 있어 가독성 ✅
  • 해당메서드에서 예외처리 ❌ → 해당메서드를 사용하는 쪽이 예외를 처리하도록 책임전가
public class ExceptionDemo {

	public static void main(String[] args) {
    	Scanner scanner = new Scanner(System.in);
        
        try {
        	System.out.println("파일 이름을 입력하시오");
            
            String fileName = scanner.nextLine();
            
            File f = createFile(fileName);
        } catch (Exception e) {
        	System.out.println(e.getMessage());
        }
        
    }
    
    static File createFile(String fileName) throws Exception {
    	if (fileName == null || fileName.equls("")) {
        	throw new Exception("파일이름이 유효하지 않습니다");
        }
        
        File f = new File(fileName);
        f.createNewFile();
        return f;
    }
}
profile
🐱Sunyeon-Jeong, mallang developer🐰

0개의 댓글