DevCastleOne

목차]

- 자바에서 예외처리 하는 방법 ( try , catch , throw , throws , finally )

- 자바가 제공하는 예외 계층 구조

- Exception과 Error의 차이는?

- RuntimeException과 RuntimeException이 아닌것의 차이는?

- 커스텀한 예외 만드는 방법

 

 

예외란?

자바에서 예외라는 것은 두가지의 경우가 있을수 있다.

오류(Error)와 예외(Exception) 이다.

 

오류(Error)

: 시스템 레벨에서 발생하기 때문에 개발자가 제어할수 없으며 심각한 문제다.

 

예외(Exception)

: 개발자가 미리 발생할 문제를 예측하여 처리할수 있다. ( 로직으로 제어 가능 )

 

 

예외 클래스 구조

 

 

자바의 모든 예외 클래스는 Throwable 클래스를 상속 받고 있고

예외 클래스는 크게 Exception 과 Error 로 나뉜다.

Error는 시스템 레벨에서 심각한 수준의 에러를 의미하며 개발자가 의도한 대로 제어할수가 없다.

Exception은 개발자가 의도한 대로 제어할수 있다.

 

Exception은 Checked Exceptions와 Unchecked Exceptions로 나뉜다.

Runtime Exception과 상속받은 클래스들은 모두 UnCheckedException이고

Runtime Exception을 제외한 클래스는 모두 checkedException이다.

 

Checked Exception

1. 반드시 예외 처리를 해야함

2. 컴파일 시점에 확인됨

3. 예외 발생시 트랜잭션 Roll-back 하지 않음

4. IOException , SQLException....

5. 반드시 try/catch , throws으로 반드시 처리해야한다. ( 무조건 명시적으로 제어해야함 )

 

Unchecked Exception

1. 명시적인 처리를 강제하지 않음

2. 실행시점에서 확인됨

3. 예외 발생시 트랜잭션 Roll-back 함

4. NullPointerException , IllegalArgumentException...

5. 미리 예측하지 못했던 문제에서 발생하며 충분히 발생할 만한곳에서 개발자가 처리를 해줘도 되고 하지 않아도 된다.

 

 

 

예외 처리 방법 try , catch , throw , throws , finally

 

try , catch , finally는 예외가 발생한 메소드 내에서 직접 처리할때 사용함

 

try{
 //예외 발생 가능한 코드
}catch(예외타입클래스1 매개변수명){
 //예외타입1의 예외가 발생했을때 작업 코드
}catch (예외타입클래스2 매개변수명){
 //예외타입2의 예외가 발생했을때 작업 코드
}finally{
 //무조건 처리해야하는 코드
}

 

try

- 블록내에서 예외가 발생할수 있는 범위를 지정하기 위해 사용

- catch 문이 반드시 하나는 같이 존재해야함

 

catch

- 예외가 발생했을때 처리하기 위한 구문으로
- 반드시 Throwable 클래스의 하위 클래스 타입으로 선언되어야 한다.

 

finally

- 예외의 발생 유무 상관없이 반드시 작업해야 하는 코드가 들어가야 한다.

 

 

throws

- 예외가 발생한 메소드를 호출한 곳으로 예외 객체를 넘기는 예외 처리방법

- try-catch , try-catch-finally 블록을 이용하여 예외를 처리하지 않아도 예외처리 가능

 

    static void test() throws ClassNotFoundException {
        System.out.println("예외발생전");
        Class.forName("a.b.c");
        System.out.println("예외발생후");
    }

    public static void main(String[] args) {

        try{
            test();
        }catch (Exception e){
            System.out.println("찾을수 없음");
        }

    }

throw

- 인위적으로 예외를 발생시킬때 사용하는 명령어

- 개발자의 의도한 케이스에 맞는 경우 에러를 호출할때 사용함

 

   static void test(int num) throws Exception {

        System.out.println("come in");
        if(num==1){
            throw new Exception();
        }
        System.out.println("come out");

    }

    public static void main(String[] args) {

        try{
            test(1);
        }catch (Exception e){
            System.out.println("찾을수 없음");
        }

    }

 

e.printStackTrace() 란?

catch 구문에서 e.printStackTrace()를 사용하는 경우를 많이 보게 된다.

메소드를 호출하게 되면 예외가 발생하기 전까지의 이력을 보여주게 되는데

이것을 통해 개발자들은 예외를 추적하고 수정한다.

 

그런데 이력은 어떻게 알수있는것일까?

메소드는 호출하게 되면 메모리의 stack 영역에 stack frame이 쌓이게 되는데

JVM은 stack에 쌓여있는 stack frame들을 하나씩 pop 하여 출력한다.

 

 

예외의 전파

unchecked exception가 발생할수 있는 코드에서 예외처리를 당연히 하는게 맞지만

하지 않아도 된다.

그럼 발생할 코드에서 예외처리를 하지 않게 되면 Exception은 어디로 가게 될까?

먼저 결론부터 말하면 상위로 올라가게 된다.

 

Exception이 발생하면 Exception Handler가 처리하게 되는데 Exception Handler를 찾는 방식은 아래와 같다.

메소드는 호출할떄마다 Call Stack에 쌓이게 되고 

에러가 발생하면 역순으로 내려가면서 Exception Handler를 찾게된다.

Exception Handler 가 처리할수 있는 예외타입이면 처리하고 아니면 상위로 전달하게 된다.

 

만약 적절한 Exception Handler를 찾지 못하면 JVM 까지 전달되어 최종적으로 JVM이 Exceptiond을 처리하게 됨

 

public class ExceptionTest {

    public static void main(String[] args) {

        System.out.println("1. start");
        ExceptionTest exceptionTest = new ExceptionTest();

        try{
            exceptionTest.something();
        }catch (Exception e){
            System.out.println("5. exception");
            e.printStackTrace();
        }

    }

    private void something(){
        System.out.println("2. start");
        try{
            occursExcept();
        }finally{
            System.out.println("4.finally");
        }
    }

    private void occursExcept(){
        System.out.println("3. start");
        String code = null;
        code.length();
    }


}

 

커스텀한 예외 만드는 방법

- checked Exception을 구현하기 위해선 Exception 클래스를 상속 받아야함

- unchecekd Exception을 구현하기 위해선 RuntimeException 클래스를 상속받아야함

'JAVA' 카테고리의 다른 글

JAVA] Enum은 무엇인가?  (0) 2021.02.06
[JAVA] 자바 패키지란?  (0) 2020.12.30
자바 Dispatch란? ( static , dynamic , double Dispatch )  (0) 2020.12.25
자바 상속이란?  (0) 2020.12.25
[JAVA] 클래스란?  (0) 2020.12.16

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band