Backend/Java

Java 예외 처리 정리

가은파파 2021. 1. 16. 21:35

# 목표

  • 자바에서 예외 처리 방법 (try, catch, throw, throws, finally)
  • 자바가 제공하는 예외 계층 구조
  • Exception과 Error의 차이는?
  • RuntimeException과 RE가 아닌 것의 차이는?
  • 커스텀한 예외 만드는 방법

 

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

try ~ catch : try를 활용해서 코드를 실행 시키고, catch 조건에 맞는 예외 발생시 작성된 코드대로 예외 처리를 시킬 수 있다.

finally 는  예외처리된 후에도 실행될 수 있게 코드작성을 할 수 있다. 

import java.io.FileWriter;
import java.io.IOException;

public class Exception {
    public static void main(String[] args) throws IOException{
        FileWriter f = null;
        try {
            f = new FileWriter("data.txt");
            f.write("Hello");                
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(f != null){
                try {                
                    f.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

try~resources

Java에서 File을 사용하거나, Network를 연결하거나, DB를 연결할 수 있다. 이런 경우를 모두 Resource라고 한다.

import java.io.FileWriter;
import java.io.IOException;

public class ExceptionRe {
    public static void main(String[] args) {
        //try with resource statements
        try (FileWriter f = new FileWriter("data.txt")) {
            f.write("Hello"); 
        } catch (IOException e) {
            e.printStackTrace();            
        }        
    }
}

Java 9주차 스터디 방송 중 문제 & 솔루션

import java.io.*;

public class Example {
    public static void copy(String src, String dest) throws IOException{

        //문제가 있는 소스
        InputStream in = null;
        OutputStream out = null;
        
        try {
            in = new FileInputStream(src);
            out = new FileOutputStream(dest);
            byte[ ] buf = new byte[1024];
            int n;
            while ((n = in.read(buf))>=0)
                out.write(buf , 0, n);
        } finally {
            if(in != null) in.close();
            if(out!= null) out.close();
        }
    
        //try ~ resources로 해결(java 8이상)
        try (
        InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dest)
        ){
            byte[ ] buf = new byte[1024];
            int n;
            while ((n = in.read(buf))>=0)
                out.write(buf , 0, n);
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}

 

throw, throws  내가 직접 예외를 발생시킬 수도 있다. 폭탄던지기와 같다 그러므로 아래와 같은 throw, throws 진행 후에 try~catch 작업이 진행된다.

1. throw new Exception("문제가 발생했습니다.");

2. throws Exception

3. throws Exception

4. try.. catch.. finally

 

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

자바는 예외 계층 구조를 가지고 있어서, 예외의 우선순위가 존재한다.

ex. ArithmeticException api java로 검색하여 계층구조를 확인한다.

ArithmeticException 예외의 계층 구조

해당 Exception의 계층구조를 확인하고 개발을 진행한다. catch문의 순서를 코딩하는데 잘 활용한다.

 

# Exception과 Error의 차이는?

에러는 크게 컴파일 에러와 런타임 에러로 구분할 수 있다. 컴파일 에러는 말 그대로 컴파일 과정에서 일어나는 에러이고, 런타임 에러는 실행 과정에서 일어나는 에러이다.

컴파일 에러는 기본적으로 자바 컴파일러가 문법 검사를 통해서 오류를 잡아내 준다. 우리는 컴파일러가 알려주는 오류를 수정하면 성공적으로 컴파일을 해서 프로그램을 실행할 수 있다.

그러나 컴파일이 문제없이 되더라도 실행 과정(runtime)에서 오류가 발생할 수 있는데, 이런 런타임 에러를 방지하기 위해서는 프로그램 실행 도중 일어날 수 있는 모든 경우의 수를 고려하여 대비할 필요가 있다.

 

자바에서는 런타임 에러를 예외(Exception)와 에러(Error) 두 가지로 구분하여 대응하고 있다.

에러 메모리 부족(OutOfMemoryError), 스택오버플로우(StackOverFlowError)처럼 JVM이나 하드웨어 등의 기반 시스템의 문제로 발생하는 것이다. 발생했을 때를 대비해서 프로그래머가 뭔가 할 수 있는게 없다. 발생하는 순간 무조건 프로그램은 비정상 종료되기 때문에 애초에 발생하지 않도록 해야 한다.

예외는 발생하더라도 프로그래머가 미리 적절한 코드를 작성해서 프로그램이 비정상적으로 종료되지 않도록 핸들링 해줄 수 있다.

 

 

출처 : https://javakickoff.blogspot.com/2018/09/checked-vs-unchecked-exception-in-java.html

 

# RuntimeException과 RE가 아닌 것의 차이는?

Exception은 2가지로 나눌 수 있다.

1. Checked Exception : RuntimeException을 제외한 모든 Exception은 모두 Checked Exception이다.

try~catch문 같은 예외 처리를 해줘야 컴파일이 된다. 왜냐하면 Exception은 컴파일 시 발생하는 예외이기 때문이다.

 

ex.

CloneNotSupportedException
ClassNotFountException
IOException (subclass of IOException  : FileNotFoundException ) : 입출력 관련 예외
ParseException
InterruptedException
SQLException

 

2. UnChecked Exception : RuntimeException과 RuntimeException의 하위 계층 Exception이 Unchecked Exception이다.

try~catch문을 쓰지 않아도 컴파일이 된다. 왜냐하면 RuntimeException은 실행 시 발생하는 예외이기 때문이다.

 

※ 예외발생시 rollback 함(Unchecked)  & 예외발생시 rollback 하지 않음(Checked) : 관련된 이야기는 Spring에서 설정된 기본설정이다. 그러나 변경할 수 있음.

 

ArithmeticExeception
NumberFormatException
NullPointerException
ArrayIndexOutOfBoundException
ClassCastException

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

기존에 정의된 예외 클래스 외에 필요에 따라 새로운 예외를 정의할 수 있다. Exception 클래스를 상속받거나, 필요에 따라 알맞은 예외 클래스를 상속받아 만든다.

추가내용

1. 기존의 exception을 활용하는 것이 좋음. 

2.  throw 전달시에 e도 같이 전달해야 근본적인 exception이유를 찾을 수 있다.

public class ExceptionDemo {

    public static void main(String[] args) throws SpaceException {
        methodA(5);
    }

    static void methodA(int space) throws SpaceException {
        if (space < 1) {
            throw new SpaceException("공간 부족");
        }
    }
}

class SpaceException extends Exception {
    public SpaceException(String message) {
        super(message);    // 조상 클래스인 Exception의 생성자 호출
    }
}

# Multi code

Java 7부터 2개의 Exception을 한번에 사용할 수 있다.

public class Example {
    public static void main(String[] args) {
        try {
            throw new NullPointerException();
        } catch (NullPointerException | IllegalArgumentException e) {
            System.out.println("error");
            //TODO: handle exception
        }
    }
}

주의. 상속관계를 같이 써서는 안된다.

 

예를들어 RuntimeException 계열은 예외처리를 할 필요가 없다. 하지만 Checked Exception은 throw 전파시켜 JVM까지 보내는 코딩처리를 해야한다.

 

 

참고.

- 생활코딩

- wisdom-and-record.tistory.com/46

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

[Java] 클래스  (0) 2021.01.20
[Java] 선택문, 반복문  (0) 2021.01.18
Junit5 문법 / 예제 / 활용 방법  (0) 2021.01.16
연산자 (3주차)  (0) 2021.01.12
자바 데이터 타입, 변수 그리고 배열 (2주차)  (0) 2021.01.11