2025. 1. 7. 23:53ㆍ프로그래밍 언어/Java
개요
오늘 내일 배움 캠프의 계산기 과제를 진행을 하면서 생긴 문제를 해결하는 방법을 소개를 하려한다.
문제가 생긴 부분을 어떻게 해결했는지 같이 확인을 해보자.
전체 구상도
사용하는 툴에서 <T>값이 나오지 않아서 따로 적는다.
ArithmecticCalculator<T extends Number>
Calculator<T extends Number>
List<String>
이렇게 타입매개변수를 가진다.
문제점
제네릭 클래스을 사용하면 해당 .java -> .class로 변환이 될 때 확정이 되지 않기 때문에 연산이 되지 않는 점을 알았다.
전개
package java.lang;
import java.io.Serializable;
public abstract class Number implements Serializable {
private static final long serialVersionUID = -8742448824652078965L;
public Number() {
}
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
public byte byteValue() {
return (byte)this.intValue();
}
public short shortValue() {
return (short)this.intValue();
}
}
방법을 찾아보니 Number클래스는 계산하는 메소드가 없다고 진행이 되지 않는 문제가 있었다.
가능한 방법을 찾아 진행을 하게 되었다. 다른 방법을 찾아보니
BiFunction 으로 나중에 계산방식을 람다형식으로 넣어줄 수 있다는 점을 찾았다.
BiFunction 정리
2개의 인자를 받고 1개의 객체를 리턴하는 함수형 인터페이스3개의 인자를 받고 1개의 객체를 리턴하는 함수형 인터페이스
velog.io
절정
결론적으로는 타입매개변수을 나중에 BiFunction 을 나중에 타입매개변수를 정의하는 것도 안된다는 점을 확인했습니다.
그래서 결론적으로 생각을 했을 때
Integer -> Double 형변환은 가능하고
Double -> Integer 의 형변환은 안된다.
이유는 Double이 더 큰 변수이기 때문이다.
그래서 Double로 계산을 진행을 하고 리턴을 받을 때 형변환을 하면 계산에 문제가 없게 된다.
추가적으로 Enum 클래스에 람다로 계산식을 미리 넣어두고 나중에 꺼내어 사용하는 형식으로 진행을 하면
나중에 더 많은 계산을 추가할 때, Enum class 만 내용을 추가하면 되기 때문에 재사용성도 좋다.
결말
Integer 보다 더 큰 형태인 Double로 미리 형식을 정해두고
계산 식을 Enum으로 만들어서 최적화면에서 더욱 좋아진 부분이 있다.
하지만 아쉬운점은 타입매개변수<T> 로 ArithmeticCalculator에서 계산이 전부 끝나면 좋았겠지만,
제네릭 타입매개변수로 인해 제네릭의 형식이 정해지지 않아서
계산식을 ArithmeticCalculator 안에 못넣은 것은 아쉽다고 생각한다.
그리고 튜터님께 들고갔지만 내가 생각하는 형식으로 진행을 하기엔 문제가 안맞다고 말씀하셨다.
진짜 아쉬운 부분이다.
해결 방법으로 상담한 것 중 하나로
Number class를 상속받는 커스텀 class를 만들고, 커스텀 class 안에 계산이 가능한 식을 만들어 둔다면,
ArithmeticCalculator 에서 계산이 진행이 가능할 것이다.
테스트 결과
Calculator<Double> calculator = new Calculator<>();
calculator.initalize("0.013+0.01", Double::parseDouble);
calculator.calculate(); // 결과 : 0.023
마무리
1. 제네릭 클래스는 타입매개변수가 정해지지 않아서 내부에서 계산 같은 형식이 정해져야되는 것은 오류가 난다.
2. BiFunction으로 순수함수를 람다로 지정을 해놓을 수 있다.
3. Enum 에 final 처럼 여러가지를 미리 저장을 해둘 수 있다.
이번에 계산기를 풀어보면서 자바 제네릭과 Enum을 처음 써봤는데,
Enum은 있다면 정말 코드가 많이 깔끔해지는 모습을 직접 확인을 했고,
제네릭은 너무 어려워서 여러번 봐야지 알것 같다는 느낌이 들었다.
오늘 제네릭만 5시간 이상 봤다..
다들 행복한 하루가 되길 바라며.
'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] 추상 클래스에 대해서.araboza (1) | 2025.01.15 |
---|---|
[트러블 슈팅] 키오스크 과제 with Java (0) | 2025.01.13 |
[Java] 내일배움캠프 계산기 과제 분석을 해보자. (1) | 2025.01.10 |
[Java] try - catch - finally 의 사용법 with Spring boot (2) | 2025.01.03 |
[Java] Arrays.sort() vs Arrays.stream() 에 대해서.araboza 1편 (2) | 2024.12.27 |