개발 강의 정리/JAVA

[JAVA] 예외처리 코드, 사용자 정의 예외

심사기 2021. 6. 29. 11:44

1. 예외처리코드

 

1. Try-Catch 블럭

catch 블럭엔 무엇을 넣어야 하는가? 

 

=> 비즈니스 로직이기 때문에 임의로 만들 수 없음

 

 

public static void main (String [] args){
	
    try{
    
    }catch(예외 클래스 e){ //예외클래스 참조변수명 => 매개변수
    
    //발생한 예외 객체의 메소드를 호출하여, 로그로 스택 트레시으(Stack Trace)가 남도록 호출 해줘야함. 
			
      e.printStackTrace();
    
    }catch(예외 클래스 b){
    
    } 
    .
    .
    .
    finally{ //JVM이 수행을 보장하는 블록
    //try 블럭에서 사용된 자원객체를 해제
    }

}

 

 

2. 다중캐치

 

catch 블럭을 여러개 사용해서 여러 예외를 잡을 수 있다. 

 

Exception 캐치문이 위로 올라가면 나머지 캐치 블럭에 도달하지 못하기 때문에

작은타입에서 큰 타입 순으로 작성해야한다. 

 

 

정상코드

catch(ClassNotFoundException e){		//Checked Exception 예외처리
			e.printStackTrace();
			
			;;
}catch(NullPointerException e){			//Runtime Exception 예외처리
			e.printStackTrace();
			
			;;
}catch(Exception e){	//위의 2가지 예외를 제외한 그 나머지 모든 발생 가능한 예외처리.
			e.printStackTrace();
			
			;;
}

 

컴파일 오류! 

		catch(Exception e){			//조상 클래스인 Exception
			e.printStackTrace();
			
			;;
		}catch(ClassNotFoundException e){		//Checked Exception 예외처리
			e.printStackTrace();
			
			;;
		}catch(NullPointerException e){			//Runtime Exception 예외처리
			e.printStackTrace();
			
			;;
		}

 

 

3. 멀티 캐치

 

 

catch문이 두개 이상이면 "다중 캐치"라고 한다. 

 

만약에 각 catch 블럭에서 수행할 예외처리 코드가 비슷하다면 굳이 catch 블럭을 쓸 필요가 있겠느냐? 

=> 이럴땐 "멀티 캐치"를 사용한다. 

 

예외가 동시에 발생할 수는 없게 때문에 멀티 캐치가 사용 가능하다. 

		catch(NullPointerException | NullPointerException e){ //멀티 캐치
			e.printStackTrace();
			
			log.info(e);
		}

 

 

 

3. 예외 던지기

public static void main(String[] args) 
			throws ClassNotFoundException,IOException, SQLException {
		
		log.debug("main(args) invoked.");
		
		try {
			Class clazz = Class.forName("java.lang.String2");
			log.info(" - clazz :" + clazz);
			
		}finally { //JVM이 수행을 보장하는 블럭
			//try 블럭에서 사용된 자원 객체를 해제
			
		}//try finally
}        

공용 클래스같은 경우에는 throws절을 통해 위로 던진다. 어떠한 예외가 발생했다는 것을 알려주기 위해. 

 

 

 

2. 사용자 정의 예외

 

사용자 정의 예외를 정의할때에는 먼저 Runtime Exception 인지, Checked Exception 인지 판단 해야한다. 

=> 경험에 의해 결정해야한다. 

 

Runtime Excpeiton은 정말 예상하지 못한 상황에 발생한다. Runtime Exception은 정말 드물게 정의한다.

 

업무 절차에 기재 되어 있는것은 반드시 Checked Exception으로 처리한다. 

Checked Exception의 예외 처리 방법은 두가지이다.

try-catch로 처리하거나, main으로 throws하는 것인데 throws하는 것이 실무에선 일반적이다. 

업무 절차를 알아야 예외 처리를 할 수 있다. 

즉, 반드시 try-catch로 처리하거나 main으로 throws 해야할 예외라면 Exception을 extends한다. 

 

1. 사용자정의 예외 정의

 

public class BalanceInsufficientException extends Exception {

	//constructor Overloading
	
	//아래의 생성자는 예외 메시지 없이 단순히 예외 객체만 만들때 사용
	public BalanceInsufficientException() {
		;;
	}//constructor
	
	//아래의 생성자는 예외 메시지까지 생성할수 있는 생성자. 
	public BalanceInsufficientException(String message) {
		super(message);
	}//constructor
	
}//end class

 

 

2. Throw

 

 

메서드 안에서 throw 키워드를 사용하면 반드시 메소드 오른쪽에 반드시 throws 키워드를 붙여야한다. 

그러나 메서드 내부에서 명시적으로 throw 키워드를 사용해 예외를 던지든 안 던지든 throws 키워드는 사용가능하다. 

 

메서드 오른쪽 throws절에 Runtime Exception을 명시할 수 있지만 일반적으로 쓰진 않는다. 

 

public void withdraw (int money) throws BalanceInsufficientException{
		log.debug("withdraw(money) invoked.");
		
		if(balance<money) {
			//지정한 금액을 계좌에서 출금시, 잔고가 부족하면... 
			throw new BalanceInsufficientException("잔고부족"+(money-balance)+" 모자람");
		}//if
		
		balance -=money;
	}//withdraw

 

 

3. 예외 Wrapping 하기. 

 

최종적으로 던질 예외안에 다른 예외를 집어 넣는것이다. 

=> 안에 들어가는 예외가 더 큰 타입이어도 상관 없음. 

 

Wrapping 횟수는 상관 없다. 

효과=>  Console창에 Caused by 구문이 Wrapping한 횟수만큼 나온다. 

 

public static void main(String[] args)  throws IOException  {
		
		Account account = new Account();
		
		account.deposit(10000);
		
		log.info("예금액 : "+account.getBalance());
		
		//출금하기
		
		try {
			account.withdraw(30000);
		}catch(BalanceInsufficientException e) {
			
				
			//예외를 사용자 정의 Exception으로 던지는 것이 아니라, IOException으로 던지려고 할때
			//IOException에 사용자 정의 Exception을 넣는것. 
			//Exception을 Wrapping 하여 던지기 
			IOException e2=  new IOException(e); //메소드 블럭 안에서 throw 절이 있다면 메소드 오른쪽에 반드시 throws 절이 있어야한다. 
								//생성자 매개변수로 잔고부족 예외 객체로 넣는것. 
			SQLException e3 = new SQLException(e2);
            
            throw e3; //최종으로 던질 Exception 
		
		}//try-catch
		
		
	}//main