🛠️ Trouble Shooting
❗문제 발견:
콘솔에서 첫 번째, 두 번째 숫자를 입력할 때 숫자가 아닌 문자 또는 공백으로 입력할 경우 프로그램이 비정상적으로 종료되는 트러블 발생
❗문제 원인 부분:
이 문제는 Scanner 클래스에서 발생하는 입력 타입 불일치로 인한 예외 처리 부족으로 발생한다.
scanner.nextDouble()이나 scanner.next(). charAt(0) 메서드를 사용하여 값을 입력받을 때, 사용자가 예상되는 타입 (예: int, double, char)과 다른 형식의 데이터를 입력하면, 프로그램은 InputMismatchException과 같은 예외를 발생시킵니다. 이 예외가 발생하면 프로그램은 예외를 처리하지 않으면 비정상적으로 종료된다.
int first = scanner.nextInt(); // 사용자가 문자를 입력하면 InputMismatchException 발생
🔎 문제 해결:
예외 처리 (try-catch): try-catch 문을 사용하면 예외(Exception)가 발생해도 프로그램이 비정상적으로 종료되지 않고, "잘못된 입력입니다. 다시 시도하세요."와 같은 메시지를 출력하여 프로그램이 종료되지 않고 계속 실행될 수 있도록 수정했다.
📝 해결 후 전체 코드(App 클래스)
package calculator;
import java.util.Scanner;
public class App {
public static void main(String[] args) {
// 객체 생성
Scanner scanner = new Scanner(System.in);
ResultManager resultManager = new ResultManager();
ResultUpdate resultUpdate = new ResultUpdate();
ExitProgram exitProgram = new ExitProgram();
ArtimaticCalculator<Number> calc1 = new ArtimaticCalculator<>(); //사칙 연산을 처리하는 계산기 객체
while (true) {
try {
double first; // 첫 번째 숫자
double second; // 두 번째 숫자
char operator; // 사칙 연산 기호
System.out.print("첫 번째 숫자를 입력하세요: ");
first = scanner.nextDouble();
System.out.print("사칙연산 기호를 입력하세요 (+, -, /, *, %): ");
operator = scanner.next().charAt(0);
System.out.print("두 번째 숫자를 입력하세요: ");
second = scanner.nextDouble();
// ArtimaticCalculator 클래스의 calculate() 메서드를 호출
double result = calc1.calculate(first, second, operator);
// 결과 출력
if (!Double.isNaN(result)) { // 오류 발생 시 출력 안 함
System.out.println(first + " " + operator + " " + second + " = " + result);
}
// 저장된 연산 결과 출력
System.out.println("저장 리스트 목록: " + calc1.getResults());
// 결과값 리스트 삭제
resultManager.removeResult(calc1.getResults(), scanner);
// 결과값 리스트 값 변환
resultUpdate.setResult(calc1.getResults(), scanner);
// 저장된 연산 결과 출력
System.out.println("저장 리스트 목록: " + calc1.getResults());
//BadException 예외가 발생하면 해당 예외의 메시지를 출력하고,
// 일반적인 예외가 발생하면 잘못된 입력이라는 메시지를 출력
} catch (BadException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println("잘못된 입력입니다. 다시 시도하세요.");
scanner.nextLine(); // 잘못된 입력을 제거
}
// 종료 여부 확인
// ExitProgram 클래스의 exitCalculator() 메서드를 호출
exitProgram.exitCalculator(scanner);
}
}
}
❗제네릭 사용시 트러블
Operator 인터페이스에서 T에 제한을 두지 않은 경우
<예시>
// Operator 인터페이스에서 T에 제한을 사용하지 않은 경우
public interface Operator<T> {
double operate(T first, T second);
}
Operator<String> stringOperator = (first, second) -> first + second;
// String 타입에 대해서 덧셈 연산을 한다고 가정
// 실제 계산은 숫자 연산을 해야하기 때문에 숫자 타입으로만 가능하다.
❗문제 원인 부분:
<T> 타입은 어떤 타입이든지 가능한 타입이다. 예를 들어 <T>가 String 타입일 수도 있고, Integer나 Double 같은 숫자 타입이 될 수도 있다. < T>가 Number로 제한되지 않으면, String이나 Character 같은 숫자와 관련 없는 타입을 사용할 수 있기 때문에, 연산을 할 때 예기치 않은 타입 변환이 발생한다.
🔎 문제 해결:
Number 클래스는 Integer, Double, Float, Long 등 숫자 타입의 공통된 부모 클래스.
<T>가 Number를 상속받는 타입으로 제한된다면, 숫자에 대한 연산을 안전하게 처리할 수 있다.
📝 해결 후 전체 코드(Operator 인터페이스)
T extends Number로 제한을 두어 숫자 타입만 허용하는 경우
package calculator;
public interface Operator<T extends Number> {
double operate(T first, T second); // 이제 T는 반드시 Number 타입이어야 함
// operate() 메서드:두 숫자(first, second)를 받아 계산을 수행
}
이렇게 T extends Number를 사용하면 Integer, Double, Float 등 숫자 타입만 연산할 수 있도록 제한할 수 있게 되면서, 트러블을 줄이고, 타입 안전성도 확보할 수 있다.
'JAVA' 카테고리의 다른 글
JAVA - 추상클래스 (0) | 2025.03.07 |
---|---|
JAVA - Optional (0) | 2025.03.06 |
JAVA - Enum (0) | 2025.03.05 |
JAVA - 제네릭(Generic) (1) | 2025.03.04 |
JAVA로 간단한 계산기 구현 2 (0) | 2025.02.28 |