티스토리 뷰

JAVA

JAVA의 예외 처리란?

세댕댕이 2021. 11. 26. 15:34

 

# 에러의 종류

1. 컴파일 에러 - 컴파일 시에 발생하는 에러
2. 런타임 에러 - 실행 시에 발생하는 에러
3. 논리적 에러 - 실행은 잘 되는데 의도와 다르게 동작하는 에러

 

<컴파일 에러>

- 소스코드를 컴파일 하면 컴파일러가 소스코드에 대해 기본적인 검사를 수행하고 에러가 있는지를 확인해준다.

- 오타, 잘못된 구문, 자료형 체크 등 기본적인 검사 수행.

- 컴파일러는 실행 도중에 발생할 수 있는 잠재적인 오류까지 모두 잡아내지는 못한다.

- 이왕 에러가 날거면 컴파일 에러가 최고의 에러

 

 

# 에러(Error)와 오류(Exception)

에러(Error) - 프로그램 코드에 의해 수습될 수 없는 심각한 오류
오류(Exception) - 프로그램 코드에 의해 수습될 수 있는 미미한 오류

 

모든 예외의 최고 조상은 Exception 클래스이다. 

예외 클래스는 다시 두가지 종류로 나눠볼 수 있다. RuntimeException과 그 나머지들이다.

 

ExceptionClass -> 사용자의 실수와 같은 외적인 요인에 의해 발생

(FileNotFoundException, DataFormatException...)

RuntimeExceptionClass -> 주로 개발자의 실수로 인해 발생

(IndexOutofBoundsException, NullPointerException...)

 

ExceptionClass의 경우, 예외처리가 되어있지 않다면 컴파일 에러를 발생시켜 예외처리를 강제한다.

RuntimeExceptionClass 컴파일러가 예외처리가 되어있는지 여부를 확인해주지 않는다. 

 

 

# try-catch 예외처리

프로그램의 실행 도중 발생하는 에러는 개발자가 손 쓸 도리가 없다.

하지만 예외는 개발자가 "예외처리"를 함으로써 예외의 발생으로 인한 프로그램의 비정상적인 종료를 막고 정상 운영 상태를 유지할 수 있도록 할 수 있다. (예외처리를 하지 못하면 에러와 동일하게 프로그램이 비정상적으로 종료된다)

 

 

* try-catch 문에서의 흐름

1. try 블럭 내에서 예외가 발생 -> 발생한 예외와 일치하는 catch 블럭이 있는가?

-> 있으면 try 블럭을 곧바로 빠져나가 catch블럭 내에 있는 문장들을 수행. 이후 try-catch문을 빠져나간다

(try 블럭에서 예외 발생 시, 예외 발생 위치 이후의 문장들은 수행되지 않는다.)

-> 없으면 예외를 처리하지 못하고 비정상 종료.

 

2. try 블럭 내에서 예외가 발생하지 않으면 catch 블록을 실행하지 않고 try-catch문 탈출, 다음 문장 수행.

 

try 문에서 예외 발생 -> 해당 예외에 해당하는 클래스의 인스턴스 생성 -> 해당 예외를 처리할 수 있는 catch 블럭이 있는지 순차 탐색 (instanceof 연산자를 통해) -> 있으면 예외처리 수행

 

(Exception 클래스는 모든 예외 클래스의 조상 클래스이므로, Exception 타입을 선언하면 모든 예외를 받을 수 있다)

 

 

* try-catch 예외처리 시 유의사항

1. try 블럭 또는 catch 블럭 안에 또다른 try-catch문이 들어갈 수 있다.

- 이 경우, 같은 이름의 참조변수를 사용할 수 없다.

 

2. 예외를 받을 수 있는 catch 블럭이 여러개 있을 경우, 가장 먼저 있는 catch 블럭만 수행한다.

 

* prinitStackTrace() 메서드로 예외발생 당시의 메서드 정보돠 예외 메시지를 화면에 출력할 수 있다

* getMessage() 메서드로 발생한 예외클래스의 인스턴스에 저장된 메시지를 얻을 수 있다

 

 

* 메서드에 예외 선언하기

메서드의 선언부에 예외를 선언한다 -> 메서드 내에서 발생할 수 있는 가능성이 있는 예외를 메서드 선언부에 명시해둠으로써 메서드를 호출하는 쪽에서 이에대한 예외처리를 하게끔 강요한다.

 

* 예외를 메서드의 선언부에 명시하는 것은 자신을 호출하는 메서드에게 예외를 전달하여 예외처리를 떠넘기는 것이다.

- 다른 메서드에게 계속 예외처리를 떠넘기다가 main메서드까지 가서도 예외를 처리하지 않으면 프로그램이 비정상적으로 종료된다.

 

 

# try-catch-finally 예외처리

finally 블럭은 예외의 발생 여부와 관계없이 항상 실행되야 하는 경우에 사용된다.

 

예외가 발생한 경우: try -> catch -> finally
예외가 발생하지 않은 경우: try -> finally
try {
  ...
} catch (Exception e) {
  ...
} finally {
  // 반드시 실행되야 하는 내용
}

* try 혹은 catch문에서 return 문을 만나는 경우에도 finally문은 정상적으로 실행된다.

 

 

# try-with-resources 예외처리

try-catch 문에서 사용을 마치고 자원을 반환해줘야 하는 경우 try-with-resources 예외처리 사용을 고려해볼 수 있다.

try-catch-finally 문을 사용할 수 있으나, 자원을 반환하는 close() 메서드 역시 예외를 발생시킬 수 있다는 것이 문제이다.

 

따라서 try() 블록의 괄호 안에 객체를 생성하는 문장을 넣어 try문이 종료되는 순간 자원을 반환하는 메서드가 수행되도록 해준다. (해당 객체가 AutoCloseable 인터페이스가 구현되어있어야 함)

 

 

# 사용자 예외 설계

class Myxception extends Exception {
    
    private finai int ERRCODE;
    
    MyException(String msg) {
        super(msg);
    }
    
    MyException(String msg, int errCode) {
        this(msg, 404);
    }
    
    public int getErrCode() {
        reutrn ERRCODE;
    }
}

최고 조상인 Exception 클래스를 상속받거나, RuntimeException 클래스를 상속해서 사용한다.

- RuntimeException을 상속하는 경우는 컴파일 시 unchecked 된다.

 

'JAVA' 카테고리의 다른 글

생성자 인자가 많을때는 빌더 패턴  (0) 2022.07.15
생성자 대신 정적 팩토리 메서드  (0) 2022.07.15
인터페이스란?  (0) 2021.11.25
추상 클래스란?  (0) 2021.11.25
자바 람다식과 스트림  (0) 2021.11.12
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함