본문 바로가기

자바/정리

(JAVA) 예외

코딩을 하다 보면 코드를 잘 못 짜서 에러가 발생하고 빨간 글씨 뜨며 프로그램이 멈추는걸 본적 있을것이다.

 

하지만 오류가 out of memory 같은 프로그램 실행 자체에 영향을 주는것이 아닌, 작은 오류 라면 그걸 자바는 예외 라고 부르기로 했다.

 

즉 에러(Error)는 컴파일,런타임 에러 같은 프로그램의 자체적인 문제.

그것이 아닌 우리가 해결할수 있는 범주에 있는 오류는 예외(exception) 라고 부른다.

 

컴퓨터 혹은 휴대폰에 있는 계산기를 실행 시켜보자 어떤 값을 입력하고 0으로 나누어 보자. 뭐라고 뜨는가?

 

상식적으로 수는 0으로 나눌수가 없다. 그건 계산기를 쓰는 사람들이 알아야할 법칙이다. 하지만 입력한다면

 

프로그램마다 다르겠지만 대부분 0으로 나눌수 없습니다 라고 개발자가 사전에 작성한 문구가 뜰것이다.

윈도우 기본 계산기임

원래는 오류 뜨면서 바로 강제 종료 될텐데 그걸 막아 주었다. 이것이 예외 처리 이다.

 

시작하기 앞서 오늘 배울 내용은 try~catch, finally, throws,throw 총 4가지가 될 것이다. 그 어떤 곳보다 최대한 쉽게 설명 할테니 인내심을 가지고 읽으면 좋을 것 같다.

 

먼저 try~catch, finally 사용 예제를 살펴 보자.

 

import java.util.InputMismatchException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        int num1, num2;
        char oper;
        for (; ; ) {
            try {
                System.out.print("처음수 입력 : ");
                num1 = input.nextInt();

                System.out.print("연산기호 입력 : ");
                oper = input.next().charAt(0);

                System.out.print("두번째 수 입력 : ");
                num2 = input.nextInt();
            }
            catch (InputMismatchException e) {
                System.out.println("잘못된 형식 입력했음");
                break;
            }
            try {
                {
                    if (oper == '+') {
                        System.out.println("결과는 " + (num1 + num2));
                    } else if (oper == '-') {
                        System.out.println("결과는 " + (num1 - num2));
                    } else if (oper == '*') {
                        System.out.println("결과는 " + (num1 * num2));
                    } else if (oper == '/') {
                        System.out.println("결과는 " + (num1 / num2));
                    } else System.out.println("입력값이 잘못되었습니다. + - * / 만 입력 가능합니다.");
                }
            }
            catch (ArithmeticException e) {
                System.out.println("0으로 못나눔");
                break;
            }
            finally {
                System.out.println("무!조!건!실!행!");
            }
        }
    }
}

 

위에 예제는 계산기를 변형한 코드 이다.

 

예제의 계산기는... 아래와 같은 간단한 기능들을 가지고 있다.

그런데 숫자를 int형에 숫자를 안집어 넣고 문자를 넣으면 어떻게 될까?

 

사진처럼 난리난다.

 

느낌이 오는가? 이 오류를 예외 처리하면 어떻게 될까?

 

오... 프로그램이 안튕긴다. 그런데 잘 보면 가다가 예외 뜨자마자 바로 catch로 간다.(예외 뜨면 추가 진행 안함)

 

맨위에서 말한 0으로 나누기도 한번 해보자.

역시 난리 난다.

 

그런데 예외 처리를 하면?

 

이렇게 쓸수가 있다.

 

이젠 코드를 뜯어보자.

 

try {
    System.out.print("처음수 입력 : ");
    num1 = input.nextInt();

    System.out.print("연산기호 입력 : ");
    oper = input.next().charAt(0);

    System.out.print("두번째 수 입력 : ");
    num2 = input.nextInt();
}
catch (InputMismatchException e) {
    System.out.println("잘못된 형식 입력했음");
    break;
}

 

코드를 보면 try가 보이고 catch가 보일것이다. 쉽다.

 

try가 오류뜰 범위를 정해주고 catch로 뭘할건지 조치를 취하는것이다. 이게 전부다. 나누기도 볼까.

 

try {
    {
        if (oper == '+') {
            System.out.println("결과는 " + (num1 + num2));
        } else if (oper == '-') {
            System.out.println("결과는 " + (num1 - num2));
        } else if (oper == '*') {
            System.out.println("결과는 " + (num1 * num2));
        } else if (oper == '/') {
            System.out.println("결과는 " + (num1 / num2));
        } else System.out.println("입력값이 잘못되었습니다. + - * / 만 입력 가능합니다.");
    }
}
catch (ArithmeticException e) {
    System.out.println("0으로 못나눔");
    break;
}

try로 오류뜰 범위 정해주고 오류 뜨면 바로 catch를 불러버린다.

 

여기까지 보면 의문이 들것이다. catch 안에 ArithmeticException e 혹은 InputMismatchException e 가 무엇이냐?

 

예외 종류이다. 위에 오류뜬 사진 보면 해당 글자가 같게 보일것이다. catch문이 해당 오류가 뜨면 아래 내용을 실행하라고 설정하고 있는 중이다. e는 그냥 이름 지은거라 원하는거 넣으면 된다.(참고로 같은 catch로 같은 예외를 여러번 쓰면 자바에서 알아서 나눠준다 이름도 같아도됨.)

 

그리고

 

finally {
    System.out.println("무!조!건!실!행!");
}

finally도 단순하다 예외건 뭐건 그냥 일단 실행 해달라는 녀석이다.

 

우리가 예를들어 메모장 저장 안하고 윈도우 종료하면 윈도우 종료 안되고 창하나 뜰꺼다. 저장되지 않은 파일이 있습니다... 그 역할이 finally다. 뭐... 구조도 위 처럼 단순하다.

 

--------------------------------------------------------------------------------------------------------------------

 

이젠 throw와 throws를 알아볼 것이다.

 

앞서 요약하면

throw는 예외를 일부러 내가 만드는것이고...(폭탄제조)

throws는 예외를 내가 처리 안하고 딴곳에다 던져버리는것이다.(폭탄돌리기)

 

코드를 살펴보자.

 

public class ExceptionTest {
    int num1,num2;
    public void enter(int num1 , int num2){
        this.num1 = num1;
        this.num2 = num2;
    }
    public void add(){

        int answer = num1+num2;
        if(answer >50){
            try {
                throw new Exception();
            }
            catch(Exception e){
                System.out.println("예외처리 성공");
            }
        } System.out.println("더하기는 "+ answer);
    }
    public void mul() throws Exception{
        int multiply = num1*num2;
        if(multiply>150)
            throw new Exception();
        System.out.println("곱하기는 "+ multiply / 2);
    }
}


 

public class Main {
    public static void main(String[] args) {

        ExceptionTest c1 = new ExceptionTest();
        c1.enter(30,50);
        c1.add();
        try {
            c1.mul();
        }
        catch (Exception e){
            System.out.println("깔끔하게 제거");
        }
    }
}

 

위의 코드는 원래는 값을 두개 입력 받아서 더하기 출력하고 곱하기 출력하는 간단한 코드이다.

 

하지만 내가 일부러 예외를 만들어 버렸다.

 

보이는 것 처럼 더하기 값이 50넘어가면 예외 뜨게 하고 곱하기도 150넘으면 예외 뜨게 만들었다.

 

우선 throw 설명하겠다.

 

if(answer >50){
    try {
        throw new Exception();
    }
    catch(Exception e){
        System.out.println("예외처리 성공");
    }

 

throw new 예외종류 치면 끝이다. 뭐 없다. 추가로 new옆에 보이는 Exception 예외는 모든 예외 포함이다.(최상위 포식자)

 

그리고 try catch 처리 안해주면 빨간줄 절대 안사라지니 코드 작성하면서 당황하지 말자.(런타임 예외 제외)

 

 

오... 뭐 빨간줄 절대 안 사라 진다면서 아래 코드는...

    public void mul() throws Exception{
        int multiply = num1*num2;
        if(multiply>150)
            throw new Exception();
        System.out.println("곱하기는 "+ multiply / 2);
    }
}

try catch 없이 예외 때려도 빨간줄이 없다...?

 

잘 보면 메서드 옆에 throws Exception 하라고 한다.

 

이유는 throws 때문이다. 이 녀석이 예외라는 폭탄을 다른곳으로 던져 버린것이다. 그럼 이 폭탄이 어디로 가느냐?

 

ExceptionTest c1 = new ExceptionTest();
c1.enter(30,50);
c1.add();
try {
    c1.mul();
}
catch (Exception e){
    System.out.println("깔끔하게 제거");
}

호출한 곳으로 돌아간다. 

 

그래서 호출한 곳에서 try catch로 예외를 처리 하지 않으면 오류나서 튕기게 된다.

 

 

 

 

구글에 수많은 블로그 및 커뮤니티 글들에 예외에 대한 정보는 방대하지만 나는 개인적으로 많은 시간을 할애할 정도로 예외를 이해하기가 다소 어려웠다... 이 글을 읽는 사람은 예외라는 것을 쉽게 알았으면 좋겠다.

 

자바를 배우는 모든 사람들이 힘냈으면 좋겠다.

'자바 > 정리' 카테고리의 다른 글

(JAVA) Object 클래스 toSting(), hashcode()  (0) 2022.12.08
(JAVA) Object 클래스 equals()  (0) 2022.12.08
(JAVA)다형성  (0) 2022.11.25
(JAVA)인터페이스  (0) 2022.11.21
(JAVA) 추상화  (0) 2022.11.17