예외 처리

JJ·2024년 7월 24일

backEnd

목록 보기
13/16

예외 클래스

예외클래스 트리구조

종류

Exception (Java Platform SE 8 )

checked Exception과 unchecked Exception

  • 컴파일러가 체크하면 컴파일 예외, checked Exception
    • IOException, SQLException, ClassNotFoundException…
  • 컴파일러가 체크 안하면 런타임 예외, unchecked Exception
    • ArithmeticException, NullPointerException…
checkedunchecked
처리 여부반드시 예외 처리해야 함, 안하면 컴파일 에러 발생명시적인 처리를 강제하지 않음
확인 시점컴파일 단계실행단계(런타임 단계)
예외 발생 시 트랜잭션 처리자바의 경우 롤백 처리 없음, 스프링은 있음자바의 경우 롤백 처리 없음, 스프링은 있음
대표 예시Exception의 상속받는 하위클래스 중 runtime exception을 제외한 모든 예외 (대표적으로 IOException)runtimeException 하위 예외 (대표적으로 NullPointerException)

Try-catch-finally

try {
	//예외가 발생할 일이 없는 로직 A
	//예외가 발생할 수도 있는 로직 B
	//예외 발생할 일이 없는 로직 C 
} catch(Exception 클래스 e) {
	//위 로직 B에서 예외가 발생하면 여기서 예외처리
}

-> B로직에서 예외가 발생했을 경우, C 로직은 실행이 안됨. 그래서 finally가 존재 아니면 try-catch 문 밖에

에러가 아닌데 예외 처리를 해주고 싶으면?

db에서 가져온 값이 null일 때, npe가 발생하지는 않지만 우리가 의도한 리턴값이 아니기 때문에 처리해줘야 함. → 객체가 null이면 exception이 발생하지 않는데 null 일 땐 무슨 값을 반환??? → throw

throw

throw? throws?

throw

개발자가 임의로 발생시키는 예외, 자바 입장에서는 예외가 아니지만 개발자가 예외로 처리하고자 할 때 사용

위 예시처럼 우리가 찾으려는 객체가 null 값이면 자바의 입장에선 예외가 아니지만 개발자가 의도한 값을 반환하지 않으므로 임의로 예외 처리를 해줄 때 사용한다.

예시코드)

public Product getProduct(int id) {
        Product gotProduct = productTable.get(id);

        try {
            if(gotProduct != null)
                return productTable.get(id);
            else
                throw new NoSuchElementException("제품이 없습니다.");
        } catch (NoSuchElementException e) {
            return new NullProduct();
        }
    }

try에서 throw를 던져주면 catch 해서 예외처리에 쓸 객체를 반환한다.

throws

에외가 터지만 호출자에게 예외를 던져버리는 것

그러면 호출자에서 try-catch로 에러를 잡아서 처리

[Service]
public Product getProduct(int id) {
	try {
		return productRepository.getProduct(id);
  } catch (NoSuchElementException e) {
		 return new NullProduct();
  }
}

[Repository]
public Product getProduct(int id) throws NoSuchElementException{
	Product gotProduct = productTable.get(id);
	
	if(gotProduct == null) throw new NoSuchElementException("제품이 없습니다.");
	return productTable.get(id);
}

unchecked와 checked

  • checked: 컴파일 시점 ex) IOException → throws를 쓰지 않으면 컴파일 에러 발생, 어디서 예외처리를 받아주는지 컴파일러 입장에서는 모르기 때문에 (아직 어떤 클래스들끼리 호출하는지 흐름을 모른다) 챗지피티: 메서드가 Checked Exception을 던질 가능성이 있는 경우, 해당 메서드는 throws 키워드를 사용하여 예외를 선언해야 합니다
  • unchecked: 런타임 시전 ex) NoSuchElementException → throws를 안써도 호출 흐름 상 어디선가 catch 해주면 됨. 그래서 throws를 안해줘도 어디선가 예외를 catch 함. 챗지피티: 메서드가 Unchecked Exception을 던질 가능성이 있는 경우, throws 키워드를 사용하여 예외를 선언할 필요가 없습니다. 호출하는 쪽에서는 이 예외를 처리하지 않아도 컴파일 오류가 발생하지 않습니다.

예외 클래스 만들기

public class ProductNotFoundException extends NoSuchElementException {
    private String message;

    public ProductNotFoundException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

예외클래스를 구체화하면 좋은 이유

  • 에러 잡기가 쉽다 = 추적이 쉽다
  • 어떤 에러인지 구체적으로 상황별로 대응할 수 있다.

예외 처리는 어디에서?

예외가 발생할 때 어디서 예외처리를 해줘야 할까?

profile
🎀👩🏻‍💻✨🐾🌷🦅

0개의 댓글