본문 바로가기

Java/Java

(JAVA) Exceptions in Java (1)

Exception이란 무엇일까?

Exception은 기대하지 않거나 원하지 않은 event 혹은 결괏값이 도출된 상태를 의미한다.

발생 시점은 런타임 동안에 일어나고 이는 프로그램의 정상적인 흐름을 방해하는 요인이 된다.

 

Error vs Exception

오류 (Error)

Error는 시스템 레벨에서 심각한 수준의 오류이다. 이는 미리 예측할 수 없기 때문에 try to catch로 예외를 잡아선 안된다.

(애플리케이션에서 오류에 대한 처리를 하지 않아도 된다.)

 

Exception

Exception은 상태를 나타내기 때문에 즉 개발자가 구현한 로직에서 나타나기 때문에 미리 예측할 수 있다.

그러므로 try to catch로 예외를 잡아야 한다.

 

http://www.nextree.co.kr/p3239/

 

Java 예외(Exception) 처리에 대한 작은 생각

일상생활에서도 기본적인 것은 고민하지 않고 습관처럼 사용하는 경우가 있다. 초급 개발자인 나에게 ‘예외(Exception)’이 바로 그런 것이었다. 처음 JAVA수업 때 강사님께 "왜 로직을 try문으로 감싸고, 또 catch(e)는 무엇인가요?"라는 질문을 한 적이 있다. 돌아온 대답은 "이렇게 안하면 에러가 나니까."였다. 나는 이것을 안 하면 어떤 일이 벌어지는지

www.nextree.co.kr


exception의 특징

exception의 계층구조

모든 exception과 Exception 하위의 클래스의 노드들은 위에 언급하였듯이 개발자가 catch로 반드시 잡아야 한다.

ex) NPE

Error 하위의 노드들은 JVM에 의해 사용되고 JDK와 함께 에러를 찾아낸다.

ex) StackOverflowError 


어떻게 JVM은 Exception을 핸들링하는가?

아래 두 가지 핸들링 기법이 존재한다.

  • Default Exception Handling
  • Customized Exception Handling

Default Exception Handling

 

메서드 내에서 어떠한 로직 처리 시 예외가 발생한다면 해당 메서드는 Exception Objectr 객체를 생성하고 JVM에 예외를 전달한다.

 

  • Exception Object는 Exception의 이름과 설명 그리고 exception이 발생한 프로그램의 현재 상태에 대한 정보를 담고 있다.

 

이러한 일련의 과정들은 예외를 던진다 라고 불린다.

 

 

예외가 발생한 메서드에 도달하기 위해서 호출된 메서드들의 목록들이 있다.

이러한 메서드 목록을 우리는 Call Stack이라 부른다.

 

Call Stack의 처리과정

 

  • 런타임 시스템이 exception이 발생한 코드 블록을 포함하는 메서드를 찾기 위해 CallStack을 탐색한다.
  • exception을 처리할 수 있는 코드 블록: Exception handler
  • 런타임 시스템은 예외가 발생한 메서드를 탐색하기 시작하며 메서드가 호출된 역순으로 CallStack을 처리한다.
  • 만약 해당 예외를 처리하기에 적절한 Exception handler를 찾는다면 default exception handler에 발생한 예외를 전달합니다. 여기서 적절한 handler는 처리할 수 있는 exception object의 타입과 예외를 던진 exception object의 타입이 일치하는 핸들러를 의미한다.
  • 만일 런타임 시스템이 callstack에 있는 모든 메서드를 탐색 후 적절한 핸들러를 찾지 못했다면 런타임 시스템은 exception object를 default exception handler에 넘긴다.
  • default exception handler는 예외 정보를 아래와 같은 형식으로 print 하고 프로그램을 비정상적으로 종료시킨다.
Exception in thread "xxx" Name of Exception : Description
... ...... ..  // Call Stack

 

Method Call Stack

public class MethodCallStackDemo {
    public static void main(String[] args) {
        System.out.println("Enter main()");
        methodA();
        System.out.println("Exit main()");
    }

    public static void methodA() {
        System.out.println("Enter methodA()");
        methodB();
        System.out.println("Exit methodA()");
    }
    public static void methodB() {
        System.out.println("Enter methodB()");
        methodC();
        System.out.println("Exit methodB()");
    }
    public static void methodC() {
        System.out.println("Enter methodC()");
        System.out.println("Exit methodC()");
    }
}

실행결과

실행과정 

1. JVM이 main을 호출한다.

2. main()은 callStack에 push되고 methodA()를 호출한다.

3. methodA()는 callStack에 push되고 methodB()를 호출한다. 

4. methodB()는 callStack에 push되고 methodC()를 호출한다.

5. methodC()가 완료된다.

6. methodB()가 callStack에서 pop되고 완료된다.

7. methodA()가 callStack에서 pop되고 완료된다.

8. main()이 callStack에서 pop되고 완료된다.

 

methodC()에서 ArithmeticException를 발생시켜보자

public static void methodC() {
    System.out.println("Enter methodC()");
    System.out.println(1/0); // divide-by-0 triggers an ArithmeticException
    System.out.println("Exit methodC()");
}

실행결과

MethodC()는 ArithmeticException 예외를 발생시킨다. 예외를 발생시킬뿐 처리하지 않고 즉시 callStack에 있는 메서드를 pop한다.

MethodB() , MethodA(), main() 순으로 pop된다.

main() 은 JVM에게 다시 해당 예외를 건내주고 프로그램은 종료되며 callStack의 과정을 콘솔에 전시한다.

 


Customized Exception Handling

Jave exception 핸들링은 하위 다섯가지 키워드들로 처리된다.

  • try, catch, throw, throws, finally

 

예외가 발생할 수 있는 코드는 try 블록 내에 위치한다.

만약 try 블록 내에서 예외가 발생한다면 이러한 예외는 던져진다.

 

당신의 코드는  catch 블록을 사용해서 이러한 예외들을 핸들링 할 수 있다.

시스템이 발생한 예외는 자동적으로 자바 런타임 시스템으로 던져진다.

 

예외를 수동으로 던지려면, throw 키워드를 사용한다.

메소드나 생성자에서 발생한 예외는 throws 키워드를 사용하여 명시해주어야 한다.

 

 

try 블록이 완료된 이후 무조건적으로 실행되어야하는 코드 들은 finally 블록에 넣어야한다.


class GFG { 
    public static void main (String[] args) { 
          
        // array of size 4. 
        int[] arr = new int[4]; 
       
        // this statement causes an exception 
        int i = arr[4]; 
          
        // the following statement will never execute 
        System.out.println("Hi, I want to execute"); 
    } 
} 

 

위의 코드의 배열은 size 4로 지정되어있지만 ([0], [1], [2], [3]) 5번째 주소를 보고있으므로 

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at GFG.main(GFG.java:9)

위와 같은 예외가 발생한다.

해당 예외가 발생하면 JVM은 비정상적으로 프로그램을 종료시킨다.

 

 

"HI, I want to execute" 를 실행 시키기 위해서는 

해당 코드를 try catch 블록으로 묶어야한다.


References

https://www.ntu.edu.sg/home/ehchua/programming/java/J5a_ExceptionAssert.html

 

Exception Handling & Assertion in Java

Exception Handling Introduction An exception is an abnormal event that arises during the execution of the program and disrupts the normal flow of the program. Abnormality do occur when your program is running. For example, you might expect the user to ente

www.ntu.edu.sg

 

'Java > Java' 카테고리의 다른 글

(JAVA) equals에 대해서(3)  (0) 2020.02.07
(JAVA) Exceptions in Java (2) - checked, unchecked  (0) 2020.02.04
(JAVA) autoBoxing , unBoxing의 이해  (1) 2020.02.03
(JAVA) equals에 대해서(2)  (0) 2020.01.31
(JAVA) equals에 대해서(1)  (0) 2020.01.31