import java.util.Scanner;
public class CalculatorApp {
public static boolean start() throws Exception { //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;
}
}
package org.tesk;
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("정수값");
}
this.calculator.setFirstNumber(Integer.parseInt(firstInput));
return this;
}
public Parser parseSecondNum(String secondInput) throws BadInputException {
if (!Pattern.matches(NUMBER_REG, secondInput)){
throw new BadInputException("정수값");
}
this.calculator.setSecondNumber(Integer.parseInt(secondInput));
return this;
}
public Parser parseOperator(String operationInput) throws BadInputException{
if (!Pattern.matches(OPERATION_REG, operationInput)){
throw new BadInputException("사칙연산 연산자");
}
switch (operationInput) {
case "+" -> this.calculator.setOperation(new AddOperation());
case "-" -> this.calculator.setOperation(new SubstractOperation());
case "*" -> this.calculator.setOperation(new MultiplyOperation());
case "/" -> this.calculator.setOperation(new DivideOperation());
}
return this;
}
public double executeCalculator() {
return calculator.calculate();
}
}
package org.tesk;
public class BadInputException extends Exception {
public BadInputException(String type) {
super("잘못된 입력입니다! " + type + "을 입력해주세요!");
}
}
package org.tesk;
public class Calculator{
private int firstNumber;
private int secondNumber;
private AbstractOperation operation;
public Calculator(AbstractOperation operation){
this.operation = operation;
}
public Calculator() {
}
public void setOperation(AbstractOperation operation) {
this.operation = operation;
}
public void setFirstNumber(int firstNumber) {
this.firstNumber = firstNumber;
}
public void setSecondNumber(int secondNumber) {
this.secondNumber = secondNumber;
}
public double calculate() {
double answer = 0;
answer = operation.operate(this.firstNumber, this.secondNumber);
return answer;
}
}
package org.tesk;
public class Main {
public static void main(String[] args) {
boolean calculateEnded = false;
try{
calculateEnded = CalculatorApp.start();
} catch (BadInputException e) {
System.out.println(e.getMessage());
}
}
}
과제를 스스로 해결하기 어려웠던 점
- public Parser parseFirstNum 메서드 부분에서 리턴을 어떻게 해줘야 할지 몰랐음
- 그냥 this로 리턴을 해주면 됨
- 이어서 리턴을 할 때 왜 굳이 저 메서드에서 Parser객체를 리턴해 줘야 하는지 고민을 했었다. return을 객체로 안해주면 오류가 안잡히나 생각을 해봤는데, void로 변경하고 실행해도 오류는 잘 잡혔다(당연히) 그냥 큰 이유없이 넣으신 것 같다는 결론이 나왔다
- CalculatorApp 클래스의 존재에 대해서 망각하고 있어서 도대체 parser객체로만 어떻게 해야하나 생각한 것 같다
- throws에 대한 개념이 약간 모호해서 이를 어떻게 연관된 클래스끼리 연결시켜서 던져야 되는지 어려웠던 것 같다
예외처리의 구조
- throw : 예외 객체를 생성하고, 발생된 예외는 가장 가까운 try-catch 블록에서 처리
- throws : 메서드 선언부에서 예외를 선언하면, 호출하는 쪽에서 해당 예외를 처리해야 함
public void checkDivision(int divisor) throws ArithmeticException {
if (divisor == 0) {
throw new ArithmeticException("Divisor cannot be zero.");
}
System.out.println(100 / divisor);
}
public static void main(String[] args) {
try {
checkDivision(0); // 0으로 나누기 시도
} catch (ArithmeticException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
throw를 통해 ArithmeticException이라는 예외객체를 발생시키고 가장 가까운 try catch블록에서 처리하려고 했으나 throws 가 메서드에 선언되어 있기 때문에 이 메서드를 호출한 곳으로 에러처리를 위임 -> 그래서 main 메서드의 try-catch에서 에러를 잡아서 처리
과제에서의 구조
- 메서드 옆에 throws BadInputException 이 명시되어 있기 때문에 이를 호출한 메서드로 BadInputException을 위임
public void parseFirstNum(String firstInput) throws BadInputException{
if (!Pattern.matches(NUMBER_REG, firstInput)) {
throw new BadInputException("정수값");
}
this.calculator.setFirstNumber(Integer.parseInt(firstInput));
// return this;
}
- 이를 호출한 start()도 throws가 되어있으므로 또 위임
public class CalculatorApp {
public static boolean start() throws BadInputException{
Parser parser = new Parser();
Scanner scanner = new Scanner(System.in);
System.out.println("첫번째 숫자를 입력해주세요!");
String firstInput = scanner.nextLine();
parser.parseFirstNum(firstInput);
- start()를 호출한 mian에서 catch로 에러 잡음
public class Main {
public static void main(String[] args) {
boolean calculateEnded = false;
while (!calculateEnded) {
try {
calculateEnded = CalculatorApp.start();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
-> 그냥 throw는 에러객체를 생성하고 가장 가까운 곳에 있는 try-caatch문에서 처리해야 하는 것이고, throws는 자신의 메서드를 호출한 메서드로 에러객체를 던져서 처리를 위임하는 것!
'JAVA' 카테고리의 다른 글
Lambda & Stream을 이용하여 특정 값보다 큰 값들만 조회하기 (0) | 2025.01.09 |
---|---|
제네릭을 활용한 Double타입 계산이 가능한 계산기 만들기 (0) | 2025.01.08 |
다형성을 이용한 계산기 만들기 (0) | 2025.01.06 |
자료구조 요리 레시피 메모장 만들기 / Iterator (1) | 2025.01.02 |
Array / List / Stack / Queue / Set / Map (0) | 2025.01.02 |