예외처리 문제
문제 상황)
Exception 처리 문제
// throw - 예외를 강제로 발생시킨 후, 상위 블럭이나 catch문으로 예외를던짐
// throws - 예외가 발생하면 상위 메소드로 예외를 던짐
public class ExceptionQuiz {
public static void main(String[] args) {
try {
install();
} catch (InstallException e) {
// InstallException 에는 SpaceException ,MemoryException을 원인 예외로 가지고 있음.
if (e.getCause() instanceof MemoryException)
System.out.println("InstallException의 원인 : MemoryException");
if (e.getCause() instanceof SpaceException)
System.out.println("InstallException의 원인 : SpaceException");
System.out.println(" error message : " + e.getMessage());
e.printStackTrace();
} finally {
deleteFile();
}
// checked 예외를 unchecked로 변경하려고 하는 경우
// Exception -> RuntimeException 로 형변환 처럼 되는 것 같지만 연결된 예외임.
MemoryException met = new MemoryException("unchecked 예외 용");
/** Exception -> RuntimeException 로 변경됨.
* 하지만, 실제로는 연결된 예외임.
* RuntimeException (met)
* super((Throwable)met) -> Exception((Throwable)met)
*-> super((Throwable)met) -> Throwable((Throwable)met)
* this.cause = (Throwable)met;
* Throwable class의 cause 인스턴스 변수에저장.
* 자기 자신의 원인이 되는 예외 => 연결된 예외라고 함.
*
* 결론적으로 checked -> unchecked 로 변경됨. 컴파일 체크를 하지 않게 됨. **/
RuntimeException rte = new RuntimeException(met);
} // end of main
// 설치 메소드
static void install () throws InstallException {
try {
startInstall();
} catch (SpaceException se) {
InstallException ie = new InstallException("설치중 예외발생");
/** InstallException 의 원인 예외를 등록할 수 있음.
* => 원인 예외를 InstallException 의 인스턴스 멤버변수로 관리하고 있으니,
* 연결된 예외라고 말 할 수 있음.
* 원인 예외(cause)의 실제 소유 클래스는 Throwable 임.
* 즉, Throwable 클래스의 멤버변수 (cause)임.
* 모든 예외는 자신이 발생시킨 원인 예외를 가질 수 있음. **/
ie.initCause(se);
throw ie;
} catch (MemoryException me) {
InstallException ie = new InstallException("설치중 예외발생");
ie.initCause(me);
throw ie;
}
}
// 프로그램 설치와 관련된 메소드
static void startInstall () throws SpaceException, MemoryException{
if (!enoughSpace())
throw new SpaceException("설치실패: 설치공간 부족");
if (!enoughMemory())
throw new MemoryException("설치실패: 메모리 여유 부족");
}
static void copyFiles() {
}
static boolean enoughSpace() {
// 디스크 여유 공간 체크 로직 작성, (고의로 예외를 발생시킴)
return false; // false : 공간부족을 의미. => 예외 발생 시켜야하는 상황
// true : 디스크의 설치 공간이 충분 => 예외 발생하지 않음.
}
static boolean enoughMemory() {
return false;
}
static void deleteFile() {
System.out.println("delete file");
}
} // end of class
//예외 클래스 정의
//예외 클래스 카테고리ex)
/**
* - 사용자 예외 - 100개
* - 시스템 예외 - 100개
* - 서비스 예외 - 100개
* - 운영 예외 - 100개
* -> 400개의 예외에 대해서 try{} catch() {} 초반에는 엄격하게 하는게 맞을 수 있지만,
* 안정화가 되고, 운영이 잘 되고 있는 상황에서, 신규 개발시와 수정시에
* try{} catch(){}를 하지 않아도 되도록 개발 및 유지보수 정책을 수립할 수 있음.
*
* RuntimeException class를 사용하게 되면, try{} catch() {}를 하지 않아도 되게 해줌
* => checked, nuchecked option이 존재
* - checked : 컴파일러가 검사 -> Exception의 관계를 맺어주면 됨. -> 상속
* + 예외 처리를 강제하겠다는 의미. -> 직접 예외 처리, 또는 위임 처리
* - unchecked : 컴파일러가 검사 안함 -> RuntimeException의 관계를 맺어주면 됨. -> 상속
*
*
* **/
// 설치 예외
class InstallException extends Exception {
public InstallException(String msg) {
super(msg);
}
}
// 설치 예외의 원인 예외(디스크 용량)
class SpaceException extends Exception{
public SpaceException(String msg) {
super(msg);
}
}
//설치 예외의 원인 예외(메모리 용량)
class MemoryException extends Exception{
public MemoryException(String msg) {
super(msg);
}
}