프로젝트를 성공적으로 끝마치고 그간 있었던 문제와 해결방법을 간략히 작성하였다.
if(out == "exit") vs if(Objects.equals(out, "exit")) System.out.println("종료 하시려면 'exit'를 입력해주세요");
String out = sc.next();
if (Objects.equals(out, "exit")){
break;
}
vs
System.out.println("종료 하시려면 'exit'를 입력해주세요");
String out = sc.next();
if (Out == "exit"){
break;
}
코드를 짜며, 둘 중 어떤걸 써야 할지 생각을 해보았다.
if(out == "exit")== 연산자는 메모리 주소값을 비교truetrue가 출력된다.if(Obhects.equals(out, "exit"))원하는건 메모리 주소를 비교하는것이 아니라 값을 비교하는것이기에 if(Obhects.equals(out, "exit"))을 사용하였다.
UnsupportedOperationExceptionList.of()가 불변 리스트 이며 그곳에 add()를 실행함으로 예외처리 되었다는 것을 알게 되었다.private static List<String> history = List.of();
불변 리스트를 만들고 그 후 add()를 실행하여 해당 예외가 나왔다.
this.history = new ArrayList<>();
위와 같이 수정함으로 fixd 하였다.

a + c + b라 작성한 곳에서 c가 사칙연산 기호가 아닌 연산자로 해석될 가능성이 있음을 파악하였고" "을 넣음으로서 구분을 확실히 하는것이라 생각되어 " "을 사이에 추가하였다.output = a + c + b + " = " + result;
변수 간 구분이 확실히 되지 않아 a + c + b 처리시 c가 문자열이 아닌 연산자로 해석될 가능성을 생각했고
output = a + " " + c + " " + b + " = " + result;
" "을 사이에 추가함으로 구분을 확실히 하였더니 정상 출력 되었다.
변수명
처음 프로그래밍을 배울때(약 10여년전) 변수명을 a, b, c 따위로 정하고 주석으로 설명을 적으라고 배웠는데, 요즘은 의미 있는 이름으로 변수명을 적는다고 하여 변수명을 변경 하였다.
a => fstVal
b => sndVal
c => mathSymol

이게 맞는것 같다.
가독성 및 유지보수의 편의를 위해 정수와 기호를 받는 부분을 메서드로 분리하는 작업을 진행 하였다.
static
private static List<String> history; // static으로 선언
public Calculator() {
this.history = new ArrayList<>();
}
private List<String> history;
public Calculator() {
this.history = new ArrayList<>();
}
static변수는 클래스에 속하고 모든 인스턴스가 공유한다.
static으로 지정하여 여러 객체가 같은 기록을 공유할 수 있다는 장점이 있으나 생성자 실행 시 데이터가 초기화 될 위험이 있다는 단점이 이 존재한다.
작성한 코드에서는 문제 없이 동작하지만, static변수를 꼭 써야 하는것도 아니고, 사용한다 해도 static초기화 블록을 사용하는 것이 더 효과적이여서 삭제 하였다.
history에 저장되는 문제case '/':
if (b == 0) {
System.out.println("분모에는 0이 들어갈 수 없습니다." + "\n");
break;
}
break를 사용함으로 해당 문구를 출력하고 값을 저장하는 문제가 있었다.
case '/':
if (b == 0) {
System.out.println("분모에는 0이 들어갈 수 없습니다." + "\n");
return 0;
}
return 0으로 변경함으로 잘못된 값이 저장되는것을 막았다.
Main.javacalculator.removeresult(); // 오래된 데이터 삭제
데이터 삭제 부분을 Main파일에 작성하였는데, setHistory()에서 값이 추가된 후 바로 실행되지 않으면 지정한 갯수를 초과할 수 있음으로 데이터 추가 후 즉시 removeresult() 호출하는 방법으로 변경하였다.
Calculaotr.java
public void setHistory(String savedata){
history.add(savedata);
removeresult();
}
.에 있다는걸 깨닳아.의 유무에 따라 변환하는 코드를 작성하였고, 정상작동 하였다.제네릭(T extends Number)을 활용하여 int, double타입 모두 지원하는 코드를 작성 중
double fstVal = getdataval(sc, "첫번째 숫자를 입력하세요.", Double.class);
OperatorType operatortype = getdatasymol(sc, "사칙연산 기호를 입렵하세요(+, -, *, /)");
double sndVal = getdataval(sc, "두번째 숫자를 입력하세요.", Double.class);
위와 같이 Double.class라고 직접 지정하였다.
자동으로 변환되는게 아니라 판단되어튜터 "박성원"님께 문의를 하였고, "직접 지정한다고 접근하면 상당히 힘들다. 동적 변환으로 생각해 보라"는 답을 얻었다.
정수 를 실수로 변환.
두개 의 차이는 .의 유무차이 라는것을 깨닳고
while (true){
String input = sc.next();
try{
if(input.contains(".")){
return (T) Double.valueOf(input);
} else {
return (T) Integer.valueOf(input);
}
위와 같이 if문을 활용하여 input 값에 .이 있다면 실수로 변환하고 없다면 정수로 변환하는 코드를 작성하였다.