Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

이지은님의 블로그

250103 - Java 예외 처리 개념 및 과제 코드분석(오류와 예외, throws, throw, try-catch) 본문

TIL

250103 - Java 예외 처리 개념 및 과제 코드분석(오류와 예외, throws, throw, try-catch)

queenriwon3 2025. 1. 3. 22:42

코드 문제풀이

[SQL] 코드카타 - (41)~(45)

 

[SQL] 코드카타 - (41)~(45)

문제 (41) : 조건에 맞는 도서 리스트 출력하기BOOK 테이블에서 2021년에 출판된 '인문' 카테고리에 속하는 도서 리스트를 찾아서 도서 ID(BOOK_ID), 출판일 (PUBLISHED_DATE)을 출력하는 SQL문을 작성해주

queenriwon3.tistory.com

 

 

 

▷ 오늘 배운 것

JAVA 종합반 강의를 듣고 4주차 과제를 풀면서 개념을 정리하고 코드를 분석해 보고자 한다.

 

1. 오류와 예외

  1) 예외를 정의하는 방법(throws, throw)

  2) try-catch

  3) Throwable 클래스 구성

  4) 실제 예외를 처리하는 방법

 

2. 과제 코드 분석

  1) Main .java

  2) CalculatorApp .java

  3) Parser .java

  4) BadInputException .java

 

 


 

 

1. 오류와 예외

오류(Error) 예외(Exception)
일반적으로 회복이 불가능.
주로 코드의 문제 --> 발생시 프로그램 종료
회복(인지 대응) 가능

 

오류와 예외는 컴파일유무와 확인유무에 따라 다시 나눌 수 있다.

 

 

- 컴파일 유무에 따른 오류(예외)분류

컴파일 에러(예외)  --> 주로 코드 문법이 원인 런타임 에러(예외)  --> 실행 중 발생
.java파일을 .class파일로 컴파일할 때 발생.
프로그래밍 언어의 규칙을 지키지 않았을때 사용 -> 문법에 맞게 코드를 작성하면 실행가능 
문법적으로 오류는 아니지만(컴파일 가능)
프로그래밍 실행도중 마주할 수 있는 에러(예외)

 

- 확인 유무에 따른 오류(예외)분류

확인된 에러(예외)(Checked Exception) 미확인된 에러(예외)(Unchecked Exception)
컴파일 시점에 확인되는 에러(not 컴파일에러)
예외처리를 하면 실행될 있는 에러
런타임 시점에서 확인되는 예외.
예외처리가 반드시 필요하진 않음.

 

 

 

 

1) 예외를 정의하는 방법(throws, throw)

// OurBadException 클래스
class OurBadException extends Exception {		// Exception을 상속받은 OurBadException
    public OurBadException() {
        // 생성자에서 부모클래스의 생성자 출력 설정
        super("위험한 행동을 하면 예외처리를 꼭 해야합니다!");		
    }
}


// OurClass 클래스
class OurClass {
    private final Boolean just = true;
	
    // OurBadException을 던질 수 있다는 것을 알려주는 throws(예약어)를 지정한 메소드 생성
    public void thisMethodIsDangerous() throws OurBadException {
        if (just) {
            throw new OurBadException();		//만약 just가 참이면 OurBadException() 메소드(에러)를 던짐
        }
    }
}

 

예외를 커스텀해서 발생시킨 후 지정한 예외 알림문구를 출력할 수 있다.

 

이때 사용되는 것은 메소드에 예외가 발생할 수 있다는 것을 미리 알리는 예약어 throws실제로 예외를 던지는 예약어 throw가 사용된다. 실제로 던지게 된 내가 만든 예외는 Exception을 상속받아 만든 클래스이므로 선언할때 new를 붙여 선언한다.

throws throw
메서드 이름 뒤에 붙어 메서드가 어떠한 예외사항을 던질 있는지 알려주는 예약어 메서드 안에서, 실제로 예외 객체를 던질 사용하는 예약어
여러 종류의 예외사항을 적을 수 있다. 실제로 던지는 예외 객체 하나와 같이 사용
(
throw new OurBadException();)
메소드 throws OurBadException throw 아래의 구문들은 실행되지 않고,
throw
문과 함께 메서드가 종료됨.(return 같은 기능)

 

 

 

 

2) Try-catch

public class StudyException {
    public static void main(String[] args) {
        OurClass ourClass = new OurClass();

        try {
            ourClass.thisMethodIsDangerous();
        } catch (OurBadException e) {		// 괄호 안의 예외 발생시 실행
            System.out.println(e.getMessage());
        } finally {
            System.out.println("우리는 방금 예외를 handling 했습니다!");
        }

    }
}

 

try: 예외가 있을 수 있는 코드를 작성한다.

catch: try를 실행하면서 괄호 안의 예외가 발생하면 catch안의 코드를 실행한다.

finally: 예외 발생 유무에 상관없이 출력한다.

 

 

 

3) JAVA의 Throwable 클래스 구성

 

- 문제상황을 뜻하는 Throwable 클래스가 Object 클래스를 상속한다.

- Throwable 클래스의 자식으로 에러(Error)와 예외(Exception) 클래스가 있다.

- 에러(Error) 클래스와 예외(Exception) 클래스는 각각 IOError 클래스, RuntimeException 클래스와 같이 구분하여 처리된다.(아래 사진 참고)

- 예외(Exception)에 입출력예외(IOException)와 실행중예외(RuntimeException)이 있다.

 

 

 

 

 

4) 실제 예외를 처리하는 방법

  • 예외 복구하기

: try-catch 예외처리. 현실적으로 복구가 가능한 상황이 아닌 경우가 많거나 최소한의 대응이 많아 자주 사용되진 않음

public String getDataFromAnotherServer(String dataPath) {
    try {
        return anotherServerClient.getData(dataPath).toString();
    } catch (GetDataException e) {
        return defaultData;
    }
}

 

 

  • 예외 처리 회피하기

: someMethod()에서 발생한 에러가 someIrresponsibleMethod()로 흘러감

public void someMethod() throws Exception { ... }

public void someIrresponsibleMethod() throws Exception {
	this.someMethod();
}

 

 

  • 예외 전환하기

: 예외 처리에 신경 쓰고 싶은 경우나, 오히려 RuntimeException처럼 일괄적으로 처리하기 편한 예외로 바꿔서 던지고 싶은 경우 사용

public void someMethod() throws IOException { ... }

public void someResponsibleMethod() throws MoreSpecificException {
    try {
        this.someMethod();
    } catch (IOException e) {
        throw new MoreSpecificException(e.getMessage());
    }
}

 

 

 

 

 

2. 과제 코드 분석

위 내용을 배우고 4주차 과제에서는 예외처리 기능이 담긴 계산기 문제를 풀도록 했는데, 

해당 코드 구조에 대해 분석하고 넘어가면 좋을 것 같아서 정리를 해보기로 했다.

생략된 코드들도 많은데 이는 github링크 main브릿지에 올려놓았다.

https://github.com/queenriwon/Calculator_hw.git

 

GitHub - queenriwon/Calculator_hw

Contribute to queenriwon/Calculator_hw development by creating an account on GitHub.

github.com

 

 

1) Main.java

// Main.java
public class Main {
    public static void main(String[] args) throws Exception {
        boolean calculateEnded = false;

        while(!calculateEnded){
            try{
                calculateEnded = CalculatorApp.start();
            } catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
}
  • 메인 클래스 메인 메소드에서는 throws Exception으로 예외가 올 것을 미리 예고한다.
  • calculateEnded는 계산이 끝났는지 끝나지 않았는지를 알려주는 flag역할을 하며, 계산이 끝날때까지 while반복문 안을 반복한다.
  • 만약, 중간에 예외가 발생하면 메세지를 출력한다.(e.getMessage())

 

 

 

2) CalculatorApp.java

// CalculatorApp.java

import java.util.Scanner;

public class CalculatorApp {

    public static boolean start() throws Exception{
        Parser parser = new Parser();
        Scanner scanner = new Scanner(System.in);

        System.out.println("첫번째 숫자를 입력해주세요!");
        String firstInput = scanner.nextLine();
        parser.parseFirstNum(firstInput);

        System.out.println("연산자를 입력해주세요!");
        String operator = scanner.nextLine();
        parser.parseOperator(operator);

        System.out.println("두번째 숫자를 입력해주세요!");
        String secondInput = scanner.nextLine();
        parser.parseSecondNum(secondInput);

        System.out.println("연산 결과 : " + parser.executeCalculator());
        return true;
    }
}
  • start()에서도 throws Exception으로 예외가 올 것을 미리 예고한다.
  • 예외는 주로 Parser 클래스에서 자료형과 관한 에러가 주로 발생한다.
  • retrun true 하는 값은 이 메소드를 빠져나왔을 때 반복문을 끝내는 flag 역할을 해준다.

 

 

 

3) Parser.java

// Parser.java

import java.util.regex.Pattern;

public class Parser {
    private static final String OPERATION_REG = "[+\\-*/]";
    private static final String NUMBER_REG = "^[0-9]+$";

    private final Calculator calculator = new Calculator();

    public Parser parseFirstNum(String firstInput) throws BadInputException {
        if(!Pattern.matches(NUMBER_REG, firstInput)){
            throw new BadInputException("정수값");
        }
        calculator.setFirstNumber(Integer.parseInt(firstInput));
        return this;
    }
    public Parser parseSecondNum(String SecondInput) throws ...{...}

    public Parser parseOperator(String operationInput) throws BadInputException {
        if(!Pattern.matches(OPERATION_REG, operationInput)){
            throw new BadInputException("연산자");
        }
        switch (operationInput){
            case "+": calculator.setOperation(new AddOperation()); break;
            case "-": calculator.setOperation(new SubstractOperation()); break;
            case "*": calculator.setOperation(new MultiplyOperation()); break;
            case "/": calculator.setOperation(new DivideOperation()); break;
        }
        return this;
    }
    public double executeCalculator() {
        return calculator.calculate();
    }
}
  • final로 정규표현식을 지정한다.(정규표현식은 다음 TIL에서 다룰 예정이다.)
  • 미리 정해둔 예외(BadInputException)를 각 메서드에서 throws로 예고한다.(throws BadInputException)
  • 만약 내가 예상한 예외가 생길 경우(if문 안에있는 정규표현식에 맞지 않은 값이 입력 되었을 경우), throw new BadInputException으로 예외를 던진다.
  • 예외 발생시 BadInputException 클래스 생성자에서 지정한 문자열을 받고 catch가 있는 곳으로 돌아온다.(throw는 retrun처럼 이후 코드는 실행되지 않는 특성이 있으니, setFirstNumber()나 return은 실행되지 않고 바로 catch가 실행된다.)
  • Main.java의 main()메서드에서 e.getMessage() 에러메세지를 출력한다.

 

 

4) BadInputException.java (예외정의)

// BadInputException.java
public class BadInputException extends Exception {
    public BadInputException(String type) {
        super("잘못된 입력입니다! " + type + "을 입력해주세요!");
    }
}
  • Exception 클래스를 상속받아 super로 예외발생시 출력될 메세지를 생성자를 이용해 출력할 수 있다.

 

결과

 

 

 

 

▷ 앞으로

입력에대한 예외처리는 정규표현식과 함께 사용하면 예외사항을 지정할 수 있다. 문자열 입력에 대한 처리를 잘 활용하기 위해 다음에는 정규처리식에 대해 알아보도록 하겠다.

그리고 별개로 예외처리를 더욱 잘 활용하기 위해 많은 예제들을 찾아봐야겠다는 생각이 들었다.(듣자하니 더 자세히 파보면 예외처리에 관련해 더 어려운 개념이 있다고 한다.)