JAVA Programming

Growing_HJ·2024년 5월 30일

일기장

목록 보기
14/51

2024.05.29. WED, <D + 9> ~
2024.05.30. THU <D + 10> , Exeception - 예외처리
Exception (예외 처리)
A. error과 exception의 차이
A-1. error

  • 코드로 해결할 수 없는 오류
    A-2. exception
  • 코드로 해결할 수 있는 오류 (컴파일 에러 아님)
  • 일어날 수 있는 오류에 대비해서 java에서 제공되는 문법을 활용해서 해결
  • 예외처리의 목적 : 프로그램의 비정상 종료를 막고, 정상적인 실행상태를 유지
  • 기본 문법
try { //예외처리 모니터링
  	  예외 발생한 코드 작성
  	} 
  catch (Exception e) {
  	  예외처리 코드 작성
  }
int number = 100;
		int result = 0;

		for (int i = 0; i < 10; i++) {

			// 실행유지 or 정상종료 처리되도록 Exception Handling함. 
			try { //Exception이 발생될 부분을 기입. 
				result = number / (int)(Math.random()*10);
				System.out.println(result);				
			} catch (ArithmeticException e) { // 발생한 예외에 대한 리포팅 처리. 
				System.out.println("0으로 나누기를 수행.");
			}

			//0으로 나누는 경우, java.lang.ArithmeticException 발생
			//비정상 종료. => 문제점 리포팅.  => 정상 종료가 되도록 해야 함.
			//result = number / (int)(Math.random()*10);
			//System.out.println(result);	

Exception 계층구조

  • Object
  • Throwable : checked 예외
  • RuntimeException : unchecked 예외
    +) 2. 개발자가 필요에 의해서 예외를 발생시키는 경우
try {
			throw new RuntimeException();		//runtime 에러 강제 발생
			// 개발자가 필요에 의해서 예외를 발생시키는 경우. (사용자 정의에 의한 예외)
			// 1. Exception class의 인스턴스를 생성. -> // 2. 인스턴스를 던지면 됨 (throw 사용). 
			/**Exception ue = new Exception("고의로 예외를 발생시킨 경우.");
			throw ue;**/
			
			//throw new Exception("고의로 예뢰를 발생시킴");
			
			/**	System.out.println(3);
			System.out.println(0/0); //ArithmeticException발생
			System.out.println(4); **/			
		} 
		catch (ArithmeticException ae) 
		{
			if(ae instanceof Exception) {
				System.out.println("true");
			}
			System.out.println("예외 메시지 : " + ae.getMessage());
			System.out.println("ArithmeticException");
		}
		catch (Exception e) {
			// ArithmeticException 는 Exception로 만들어진 파생 클래스임. 
			// 따라서, 다형성으로 catch가 된 것임. 
			// TODO: handle exception
			System.out.println("Exception");
			System.out.println("예외 메시지 : " + e.getMessage());
		} 
		// Exception 처리가 되었으므로, 정상종료가 됨. 
		System.out.println(5);		// 정상 종료 되었음. 
		System.out.println("프로그램이 정상 종료 되었음. ");

+) 3. 메소드에서 활용한 예외처리
=> 메소드에서 Exception 발생시켜 던지기 & 예외처리 위임

// 메소드를 생성해보자
	static void method1() throws Exception {
		method2(); // 예외처리 위임
		/*try {
			method2();			
		} catch (Exception e) {
			// TODO: handle exception
		}*/
	}
	static void method2() throws Exception {
		throw new Exception("method2(): 예외 발생 (예외처리 위임)");		//예외처리 위임
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {			
			method1(); // 위임받은 예외를 처리함. 
		} catch (Exception e) {
			// TODO: handle exception
		}
		//method1();	//비정상 종료를 의미.  => JVM에서 예외처리함. 
		System.out.println("정상종료됨");

+) 4. 예외처리의 문법1 . try - catch - fianlly

  • 기본 문법
try { //예외처리 모니터링
 	  예외 발생한 코드 작성
 	} catch (Exception e) {
  	  예외처리 코드 작성
  } finally {
    예외가 발생하던, 발생하지 않던, 처리할 코드 작성  }

+) 5. 자동 자원 반환

  • 문법) try .. with..resources...

  • 사용 목적) finally의 복잡도 높아지는 경우를 해결.
    자원해제 시 사용가능성이 높음 (입출력 처리 관련 등)

  • 사용) AutoCloseable interface를 구현한 경우에만, 자동 자원 반환 문법을 적용시킬 수 있음.
    +) 가정 상황
    try{} block 에서도 예외가 발생하고, AutoCloseable를 구현한 close() 에서도 예외가 발생한경우, 두 군데에서 발생할 예외적인 상황을 코드로 만들어야 확인가능함.
    -> 사용자 정의 Exception 두 개 작성 후, 두 개의 Exception 을, throws 시키면 됨.

    public class ExceptionEx6 {
    
    	public static void main(String[] args) {
    		// 실제로 발생한 Exception은 WorkException으로 하고,
    		// CloseException은 억제된 예외로 두면 됨. 
    		try(CloseableResource cr = new CloseableResource()) {
    			cr.resourceWork(true);
    		} catch (CloseException e) {
    			e.printStackTrace();
    		}catch (WorkException e) { //AA. 
    			e.printStackTrace();
    		}
    		System.out.println("정상종료");
    		
    	}// end of main
    }// end of class
// ex.1. 해제할 어떤 자원이 있다고 가정하고 class 작성해보기.  
class CloseableResource implements AutoCloseable{
	// 2. 자원을 사용한다고 가정한 메소드 + ex. AA
	public void resourceWork(boolean exceptionFlag) throws WorkException {
		System.out.println("resourceWork() 호출됨.");
		
		// if문의 조건이 true인 경우, if가 조건이 만족하여 exception이 발생하고
		// if문의 조건이 false인 경우, if가 조건이 불만족하여 exception이 발생하지 않는다. 
		if (exceptionFlag)
			// 발생한 예외는 위임처리 => 즉, 메소드 정의에 throws하면 됨
			throw new WorkException("WorkException 발생");
	}
//1. 사용자 정의 Exception 적용 전.
//	@Override
//	public void close() throws Exception {
//		// TODO Auto-generated method stub
//		System.out.println("close 호출");
//	}
	//2. 사용자 정의 Exception 적용 후
	@Override
	public void close() throws CloseException {
		// TODO Auto-generated method stub
		System.out.println("close 호출");
		throw new CloseException("CloseException 발생");
	}

}
// 자원을 사용시 발생하는 예외 처리용 Exception class
class WorkException extends Exception {
	public WorkException(String msg) {		//<- 생성자 만드는거임
		// TODO Auto-generated constructor stub
		super(msg);
	}
}
// 자원 해제시 발생하는 예외 처리용 Exception class 
class CloseException extends Exception {
	public CloseException (String msg) {
		super(msg);
	}
}

+) 6. 예외 되던지기 (Exception re - throwing)
-> 예외 처리 후 thorw => 직접 처리 => 위임 처리

  • 예외 되던지기 분류
    연관된 시스템이 자바가 아닌 경우, 별도의 A, B 분리된 시스템이 있다고 가정
    => A <-> B, 업무 처리시 서로 연결이 되어야 함.

+) 7. 연결된 예외 (chained exception)

  • 예외 A가 예외 B를 발생시켰다면, A를 B의 예외의 원인 이라고 함.
  • 사용 목적) 추상화, 또는 상속을 통해, 다형성을 통하여 코드 관리의 편리성을 높이기 위함.
    예시 상황) 발생한 예외를 그냥 처리하면 되는데, 연결된 예외를 사용할 수 밖에 없는 경우
  1. 하나의 큰 분류의 예외를 묶어서 관리하고 싶은 경우
  • 큰 분류의 예외로 catch해서 처리하려고 할 때, 실제로 발생한 예외를 알 수 없게 됨.
  1. 상속 관계로 exception을 정의하면 casting(형변환)이 필요해짐.
  • 파생된 exception이 많아지게 되면, casting의 부담이 높아지게 됨.
  1. checked exception을 unchecked exception으로 변경하고 싶은 경우

0개의 댓글