자바에서 ordinal은 주로 enum 타입에서 사용되는 개념으로, 열거형 상수의 순서를 나타낸다.
각 열거형 상수는 정의된 순서에 따라 고유한 정수 값을 가지며, 이 값을 통해 열거형 상수의 순서를 알 수 있다.
마치 typescript 의 enum 처럼 말이다.
java, typescript 모두 enum 의 특정 값을 지정해주지 않으면 0 부터 나간다.
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
public class Main {
public static void main(String[] args) {
Day day = Day.WEDNESDAY;
// ordinal() 메소드를 사용하여 순서 출력
System.out.println(day.ordinal()); // 출력: 3
}
}
이때 순서 의존성
이슈로 ordinal 값은 열거형 상수가 정의된 순서에 의존하므로 상수를 추가하거나 제거할 경우 기존의 ordinal 값이 변경될 수 있다.
따라서 ordinal 값을 기반으로 로직을 구현하는 것은 권장되지 않는다. 대신 enum의 다른 속성을 사용하거나 명시적인 값을 정의하는 것이 좋다.
@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public enum UseFlag {
None(255),
PartiallyUse(2),
Use(1),
NotUse(0);
private int value;
}
하지만 이와같이 명시적으로 타입을 선언하였는데도 불구하고 원하는대로 나오지 않을 때가 있다.
위 코드를 보면 분명 ordinal 을 사용하지 않고 각 필드에서 명시적으로 값을 매핑하였다.
하지만 문제는 바로 mapstrure 라이브러리의 사용에서 문제였다.
@Override
public PhraseListResponsePayload selectPhraseList(PhraseListRequestPayload phraseListRequestPayload) {
List<PhraseInfo> phraseInfoList = phraseInfoRepository.findByReqParam(phraseListRequestPayload);
ArrayList<PhraseInfoDTO> phraseInfoDTOArrayList = new ArrayList<>();
phraseInfoList.stream().skip((phraseListRequestPayload.getCurrentPageIndex() - 1) * phraseListRequestPayload.getPageSize()).limit(phraseListRequestPayload.getPageSize()).forEach(phraseInfo -> {
PhraseInfoDTO phraseInfoDTO = DTOMapper.INSTANCE.phraseInfoToPhraseInfoDTO(phraseInfo);
phraseInfoDTO.setDisasterInfo(DTOMapper.INSTANCE.disasterInfoToDisasterInfoDTO(phraseInfo.getDisasterInfo()));
phraseInfoDTOArrayList.add(phraseInfoDTO);
});
PhraseListResponsePayload responsePayload = PhraseListResponsePayload.builder().phraseList(phraseInfoDTOArrayList).build();
responsePayload.setTotalPageCount((int) Math.ceil((double) phraseInfoList.size() / (double) phraseListRequestPayload.getPageSize()));
responsePayload.setTotalItemCount(phraseInfoList.size());
return responsePayload;
}
위 코드는 jpa 에서 가져온 값을 가져와서 페이지 개수만큼 자른다음 해당 값을 response 객체에 담아주는 코드인데 여기서 로그를 찍어봐도 값이 ordinal 하게 나온다 따라서 mapstrure
와 함께 프로젝트를 작성할 땐 순서에 주의하여 사용해야한다.
즉, 아래와 같이 순서를 작성해 줘야한다.
@Getter
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public enum UseFlag {
None(255),
Use(1),
PartiallyUse(2),
NotUse(0);
private int value;
}