도찐개찐

[JAVA] 예외(Exception) 처리 본문

JAVA

[JAVA] 예외(Exception) 처리

도개진 2022. 7. 8. 11:18

오류와 예외의 차이

예외를 알아보기 위해서는 우선 오류와 예외를 구분할 필요가 있습니다.

오류(Error) :

  • 시스템이 종료되어야 할 수준의 상황과 같이 수습할 수 없는 심각한 문제를 의미합니다.
  • 개발자 예측 불가로 방지 불가

예외(Exception) :

  • 개발자가 구현한 로직에서 발생한 실수나 사용자의 영향에 의해 발생
  • 오류와 달리 개발자가 미리 예측하여 방지할 수 있기에 상황에 맞는 예외처리(Exception Handle)를 해야함.

java.lang.Throwable

  • 자바 최상위 클래스 Object를 상속
  • 오류(java.lang.Error)와 예외(java.lang.Exception)는 Throwable과의 상속관계를 맺음
  • 오류나 예외에 대한 메시지를 담는 객체
  • 예외 연결(chained exception)시 해당 정보들을 기록하는 객체
  • 하위 객체 포함 getMessage(), printStackTrace() 와 같은 콘솔 상의 에러 코드, 메시지등의 정보 활용 가능

예외의 상속 계층도

Checked Exception, Unchecked Exception

Checked Exception

  • Exception을 바로 상속 받음
  • 컴파일 시점에 예외를 catch 를 정적으로 확인
  • 컴파일 시점에 예외처리(try / catch)를 하지 않으면 컴파일 에러 발생
  • 트랜젝션 롤백(Rollback)불가
  • 예죄 발생시 메서드에서 throws 예약어를 활용해 예외를 호출한 메서드에 전달 처리 가능
// Exception을 상속받아 구현한 Checked Exception
// Position이라는 객체의 positon이 유효하지 않을 경우 던져진다.

public class InvalidPositionException extends Exception {
	public InvalidPositionException(String message) {
    	super(message);
    }
}

 

// InvalidPositionException가 발생하면 해당 생성자를 호출한 메서드로 Exception을 전달하기 위해 throws 예약어를 사용한다.

public class Position {   
    public Position(String position) throws InvalidPositionException {
        if (position.length() != 2) {
            throw new InvalidPositionException(position + "은 위치 값 형식에 맞지 않습니다.");
        }
        
        x = (int) (position.charAt(0) - 'a');
        y = Integer.parseInt(position.substring(1))-1;
    }
    
    [...]
}

 

Unchecked Exception

  • RuntimeException을 상속
  • CheckedException과 다르게 컴파일 시점에 예외를 catch 확인 하지 않음
  • 컴파일 시점에 예외 발생 여부 판단 불가
  • 트랜젝션 롤백 되지 않음
  • throws 예약어를 활용한 예외처리 불필요(명시적으로 예외처리 가능)
// RuntimeException을 상속받아 구현한 Unchecked Exception
// HttpRequest가 유효하지 않을 경우에 던져진다.

public class InvalidHttpRequestException extends RuntimeException {
    public InvalidHttpRequestException(String message) {
        super(message);
    }
}

 

// InvalidHttpRequestException을 사용. 
// throws로 던져지는 IOException은 bufferedReader.readline()에서 던지는 예외이다.

public static String extractRequestLine(BufferedReader bufferedReader) throws IOException {
    String requestLine = bufferedReader.readLine();
    if (requestLine == null) {
        throw new InvalidHttpRequestException("request line이 없습니다.");
    }

    return requestLine;
}

 

 

RuntimeException 하위 Exception 종류

클래스 이름 예외 조건
ArithmeticException 정수 값을 0으로 나누려 하는 등의 유효하지 않는 계산 조건을 사용하는 경우
IndexOutofBoundsException 객체의 범위를 벗어난 색인을 사용하려 하는 경우, 배열이나 String 객체 또는 Vector객체가 이에 해당 한다.
NegativeArraysizeException 음수 차원의 배열을 정의 하려 하는 경우
NullPointerException Null을 포함하는 객체 변수를 사용하려 하는 경우.
적절한 작업(예를 들어, 메서드를 호출하거나 데이터 맴버를 엑세스 하는)을 하기 위해서는 변수가 객체를 참조해야 한다.
arrayStoreException 배열 유형이 허락하지 않는 객체를 배열에 저장하려 하는 경우
ClassCastException 객체를 부적절한 유형으로 형 변환 하려 하는 경우 
즉, 객체가 지정한 클래스도 아니고, 지정한 클래스의 상위 클래스나 하위 클래스도 아닌 경우
IllegalArgumentException 메서드에 매개변수 유형이 일치하지 않는 인수를 전달한 경우
SecurityException 프로그램이 보안에 위배 되는 부적절한 작업을 수행하려 하는 경우 
애플릿에서 로컬 머신의 파일을 읽으려 하는 경우
IllegalMonitorStateException 스레드가 스레드에 속하지 않는 객체를 모니터하려고 기다리는 경우
IllegalStateException 적절하지 않은 때에 메서드를 호출하는 경우
UnsupportedOperationException 객체가 지원하지 않는 작업을 수행하도록 요구하는 경우

 

예외 처리 방법

try

  • 에러 발생이 가능한 코드가 위치함

catch 

  • try에서 발생한 에러이벤트를 처리
  • 다중catch 사용시에 발생할 예외 클래스의 상속을 고려

finally

  • 프로그램 종료 전에 무조건 실행
  • java.io패키지와 java.sql패키지에서 자주 사용
public class Test01 {
	public static void main(String[] args) {
		Object test = null;
		try { // test 객체는 null이 선언 되어 있지만 해당 객체를 사용함으로써 NullPointerException 발생
			test.equals(test);
		}
		catch (NullPointerException e) { // NullPointerException을 확인 하여 예외처리(예외 메시지 출력)
			System.out.println(e.getMessage());
		}
		finally {// 예외 발생 여부 관계 없이 실행
			System.out.println("종료");
		}
	}
}

/*
결과 : 

null
종료
*/
 

throw

  • 사용자가 에러 이벤트를 발생
  • 발생된 이벤트는 반드시 catch로 받아야 함
public class Test01 {
	public static void main(String[] args) {
		Object test = null;
		try { // test 객체는 null이 선언 되어 있고 조건을 통해 확인 한 경우 Exception 이벤트 강제 발생
			if (test == null) {
				throw new NullPointerException("해당 객체는 Null 이여유 ~ ㅠㅠ");
			}
		}
		catch (NullPointerException e) { // NullPointerException을 확인 하여 예외처리(예외 메시지 출력)
			System.out.println(e.getMessage());
		}
		finally {// 예외 발생 여부 관계 없이 실행
			System.out.println("종료");
		}
	}
}
/*
결과 :

해당 객체는 Null 이여유 ~ ㅠㅠ
종료
*/

throws

  • 예외 처리 미루기
  • 컴파일러에게 메소드 사용 시에 예외가 발생할 수 도 있다는 것을 사전에 알림
public class Test01 {
	public static void nullTest() throws NullPointerException { // 본 메서드 호출시 NullPointerException이 발생 될 수 있다고 알림
		Object obj = null;
		obj.equals(obj);
	}
	
	public static void main(String[] args) {
		try { // Test01.nullTest() 메서드 호출후 NullPointerException 발생시 예외 처
			Test01.nullTest();
		}
		catch (NullPointerException e) { // NullPointerException을 확인 하여 예외처리(예외 메시지 출력)
			System.out.println(e.getMessage());
		}
		finally {// 예외 발생 여부 관계 없이 실행
			System.out.println("종료");
		}
	}
}
728x90
Comments