-
[JAVA] 예외처리 및 예시(결제 시스템)OOP & JAVA 2021. 12. 4. 22:07
기본적인 예외처리 방법과 함께 예외처리로 구현한 결제 시스템 예시를 정리해 보았습니다.
예외상속도 1. try / catch / finally 문
- 에러가 발생할 경우 직접 에러를 해결하는 방법이다.
- try 에서 에러가 발생했을 경우 catch에 명시된 에러의 종류일 경우 이를 받아 처리할 수 있다.
- 예외 상속도 에 따라 상위 에러일 경우 하위 에러를 받아서 처리합니다.
- 해당 예외를 받는 catch 블럭이 없을 경우 스택 블럭을 타고 내려가면서 해당 에러를 처리할 수 있는 catch 블럭을 찾습니다.
- 메인 함수까지 올라가서 에러를 캐치하지 않으면 에러가 터져 프로그램이 종료합니다.
try{ //예외가 발생할 수 있는 코드 } catch(에러클래스1 에러변수1){ // 처리 코드 } catch(애러클래스2 에러변수2){ // 처리코드 }
2. throws 를 통한 예외 발생
: 다음 과 같이 에러를 사용자가 발생 시킬 수 도 있습니다.
if (super.getAmount() < 0) { throw new RuntimeException("overflow 발생"); } else { return true; }
3. 사용자 정의 예외 만들기
- 상황에 따라서 사용자가 자신만의 에러를 만들어 사용할 수 있습니다.
- 쓰임에 따라 원하는 예외 클래스를 상속받아 커스텀 상속클래스를 생성합니다.
// OverflowException.java public class OverflowException extends RuntimeException { private static final long serialVersionUID = 1222179582713735628L; public OverflowException(String message) { super(message); } }
//main 함수 if (super.getAmount() < 0) { throw new OverflowException("overflow 발생"); } else { return true; }
4. Checked / UnChecked 예외
- UnChecked 예외는 예외 상속도중 Runtime 예외와 그를 상속받는 모든 클래스를 말합니다.
- Checked 예외는 예외중 이를 제외한 에러들을 말합니다.
- Checked 예외를 발생 시킬 때에는 try-catch 문으로으로 throw절을 감싸거나
- throw 절이 포함된 메서드 시그내처 옆에 throws <예외클래스>를 명시해야만 합니다.
illegalArgumentException 은 예외 상속도중 runtime 을 상속받지 않으므로 checked 이고 이를 사용하기 위해 thrwos를 붙여 사용한 예시입니다.
public Wallet(final User user) throws IllegalAccessException { if (user == null) { throw new IllegalArgumentException("user cannot be null"); } }
5. 예외처리 예제 - 결제시스템
결재 과정 중간에 결재에 실패 했을때 야기되는 문제를 예외처리를 통해 해결 해보았습니다.
- 상품의 금액 만큼 사용자의 계좌에서 금액을 차감한다.
- 재품의 재고 수량을 한개 줄인다.
만약 이 결재 과정중 1번을 진행 했지만 2번을 진행하던 중 재고 수량이 없을 경우 사용자의 계좌에 돈을 다시 돌려주어야합니다.
결재를 진행하기 앞서 수량을 확인한다 하더라도 다른 사용자가 먼저 결재를 해 수량이 없어지는 경우가 생길 수가 있습니다.
<제품이 있다면>
- 지갑에서 상품의 가격만큼 차감한다.
- 창고에서 해당 제품을 제거한다.
<제품없다면>
- 지갑에서 상품의 가격만큼 차감한다.
- 창고에서 해당 제품을 제거하는 과정중 removeProduct 내부에서 ProductNotFoundException(Rumtime 을 상속받음) 을 발생시킨다.
- removeProduct 내부에서 발생한 예외는 스택 블럭을 타고 메인함수의 그자리로 넘어와 터지고 catch에서 받아진다.
- 지갑에 상품의 가격만큼을 다시 더해줍니다.
// main.java wallet.withdraw(product.getPrice()); try { warehouse.removeProduct(product.getId()); } catch (ProductNotFoundException e) { wallet.deposit(product.getPrice()); }
//warehouse.java ... public void removeProduct(final UUID id) { for (int i = 0; i < this.products.size(); ++i) { if (this.products.get(i).getId().equals(id)) { this.products.remove(i); if (isProductOutOfStockMock(i)) { throw new ProductNotFoundException("Product not found!"); } } } }
'OOP & JAVA' 카테고리의 다른 글
[JAVA] 깊은복사 (clone , 복사 생성자) (0) 2021.12.18 [JAVA] 컴포지션 vs 상속 (0) 2021.11.01 [ JAVA ] String , StringBuffer , StringBuilder 차이 (0) 2021.09.22 Java 메모리 관리 (0) 2021.09.12 커맨드에서 jar file 실행하기(feat. class path) (0) 2021.08.19