예외처리

서지우·2023년 7월 12일
0

JAVA

목록 보기
21/28

프로그램 오류

- 컴파일 에러 : 컴파일할 때 발생하는 에러
- 런타임 에러 : 실행할 때 발생하는 에러
- 논리적 에러 : 의도와 다르게 동작(실행시)

JAVA의 런타임 에러 - 에러와 예외
- 에러는 어쩔 수 없지만, 예외는 처리해야 한다

- 에러처리의 정의와 목적


try-catch

- 예외를 처리하려면 try-catch문을 사용해야 한다.

흐름


예외발생시키기


예외 클래스의 계층구조

예외 클래스는 크게 두 그룹으로 나뉜다.

RuntimeException클래스들
: 프로그래머의 실수로 발생하는 예외 -> 예외처리 선택
Exception클래스들
: 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외 -> 예외처리 필수


catch블럭

- try블럭에서 예외가 발생하면, 발생한 예외를 처리할 catch블럭을 찾음

- 첫번째 catch블럭부터 순서대로 찾아 내려가며, 일치하는 catch블럭이 없으면 예외는 처리되지 않음

- 예외의 최고조상인 Exception을 처리하는 catch블럭은 모든 종류의 예외를 처리할 수 있음( 반드시 마지막 catch블럭이어야 함)
- 발생한 예외 객체를 catch블럭의 참조변수로 접근할 수 있음.


finally블럭

- 예외의 발생여부와 관계없이 실행되어야 하는 코드를 넣음

- 선택적으로 사용할 수 있으며, try-catch-finally의 순으로 구성됨

- 예외 발생시, try → catch → finally의 순으로 실행되고 예외 미발생시 try → finally의 순서로 실행됨

- try 또는 catch블럭에서 return문을 만나도 finally블럭은 수행됨


메서드에 예외 선언

- 예외를 처리하는 또 다른 방법

- 사실은 예외를 처리하는 것이 아니라, 호출한 메서드로 전달해주는 것

- 호출한 메서드에서 예외처리를 해야만 할 때 사용


예외 되던지기(re-throwing)

- 예외를 처리한 후에 다시 예외를 생성해서 호출한 메서드로 전달하는 것

- 예외가 발생한 메서드와 호출한 메서드, 양쪽에서 예외를 처리해야 하는 경우에 사용


사용자 정의 예외 만들기

- 기존의 예외 클래스를 상속받아서 새로운 예외 클래스를 정의할 수 있음

- 에러코드를 저장할 수 있게 ERR_CODE와 getErrCode()를 멤버로 추가


실습 - ch08 / S01.java

주석으로 설명..

package ch08;
// 예외처리

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

        System.out.println("이전코드");

        // try 예외가 일어날 것 같은 코드를 담는 공간
        try {
            // 예외가 일어날 수 있는 코드
            System.out.println(10 / 0);        
        // catch 특정 예외가 발생했을 때
        // 프로그램을 멈추지 않고 처리한 뒤 다음으로 넘긴다    
        } catch (ArithmeticException e) {
            System.out.println("계산 중 예외가 발생했습니다.");
        }

        System.out.println("다음코드");
    }
}

실습 - ch08 / S02.java

주석으로 설명..

package ch08;

public class S02 {
    public static void main(String[] args) {
        
        int[] intArray = {10, 20};

        // try {
        //     // 여기서 에러 발생
        //     System.out.println(10 / 0);
        //     // 밑으로 안내려감
        //     // catch로 바로감
        //     System.out.println(intArray[2]);
        // } catch (ArithmeticException e) {
        //     System.out.println("계산중 예외가 발생했습니다.");
        // }

        // try {
        //     // intArray에서 바로 밑에 catch로 넘어감
        //     System.out.println(intArray[2]);
        //     System.out.println(10 / 0);
        //     // 발생할 수 있는 모든 에러에 대한 처리를 각각 해주는 것이 좋다.
        // } catch (ArithmeticException e) {
        //     System.out.println("계산중 예외가 발생했습니다.");
        // } catch (ArrayIndexOutOfBoundsException e1){
        //     System.out.println("배열검색 범위를 넘어섰습니다.");
        // }

        try {
            System.out.println(10 / 0);
            System.out.println(intArray[2]);
            // 중요한 코드가 아닐 경우에는
            // 한꺼번에 처리할 수도 있다
            // 최상위 예외 클래스 Exception
        } catch (ArithmeticException e) {
            System.out.println("예외가 발생했습니다.");
        }
    }
}

실습 - ch08 / S03.java

주석으로 설명..

package ch08;

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

public class S03 {
    public static void main(String[] args) {
        
        // 스캐너 -> 마지막에 꼭 close()를 해줘야함

        Scanner scanner = new Scanner(System.in);

        int num;

        try {
            num = scanner.nextInt();        } catch (InputMismatchException e) {
            num = 0;
            System.out.println("정수가 아닙니다.");
            // finally는 try안의 변수와 관련된 객체가
            // 무조건 처리되어야 할 경우 사용한다.
            // try안의 코드가 예외가 발생하든 안하든 무조건 실행된다.
        } finally {
            scanner.close();
        }

        System.out.println(num);
    }
}

실습 - ch08 / S04.java

주석으로 설명..

package ch08;

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

public class S04 {
    public static void main(String[] args) {
       
        int num;

        // try의 소괄호 안에는
        // 자동으로 close 할 수 있는 객체가 들어갈 수 있다.
        // finally로 close한 것과 같이 처리된다
        try(Scanner scanner = new Scanner(System.in);) {
            num = scanner.nextInt();
        } catch (InputMismatchException e) {            num = 0;
            System.out.println("정수가 아닙니다.");
            // finally는 try안의 변수와 관련된 객체가
            // 무조건 처리되어야 할 경우 사용한다.
            // try안의 코드가 예외가 발생하든 안하든 무조건 실행된다.
        }

        System.out.println(num);

    }
}

실습 - ch08 / S05.java

주석으로 설명..

// 직접 예외를 만들 수 있다
// Exception 또는 RunTimeException을 상속하는 것이 일반적이다
// 아래랑 같음
class NotOneException extends Exception{

    public NotOneException(String message) {
        super(message);
    }
}

class CalcUtil{
    // 들어온 정수가 1이면 정상 / 아니면 에러
    // throws는 이 함수를 호출한 곳에 에러를 던지겠다라는 뜻
    static void checkOne(int num) throws NotOneException{

        if (num == 1) {
            System.out.println("정상입니다.");
        } else {
            throw new NotOneException("에러입니다.");
        }

    }
}

public class S05 {
    public static void main(String[] args) {
        try {
            CalcUtil.checkOne(0);
        } catch (NotOneException e) {
            System.out.println(e.getMessage());
        }

    }
}
profile
미래가 기대되는 풀스택개발자 공부 이야기~~

0개의 댓글