🎯 Formatter란?
- 문자열 ↔ 객체 변환을 하되,
표시 형식(포맷팅)을 세밀하게 제어하는 데 특화된 컴포넌트ConversionService와 목적은 비슷하지만,
사람이 읽는 형태로 출력/입력되는 값을 다룰 때 특히 유용함
📚 핵심 포인트
Converter보다 표현 형식 제어에 더 초점이 있음🌐 Locale (지역/언어)
en, koUS, KRLocale.KOREA면 숫자/날짜 등에 한국식 포맷 적용🧩 Formatter 인터페이스 구조
Printer ✍️: Object → String
Parser 🔎: String → Object
Formatter는 내부적으로 Printer + Parser를 상속하여
하나의 타입에 대해 양방향 변환을 제공함
💡 Formatter 적용
- 적용 예시: 숫자 ↔ 금액 문자열
→ 목표: 숫자10000↔ 문자열"10,000"(로케일에 맞는 금액 표기)
🛠️ PriceFormatter 구현
@Slf4j
public class PriceFormatter implements Formatter<Number> {
@Override
public Number parse(String text, Locale locale) throws ParseException {
log.info("text = {}, locale={}", text, locale);
NumberFormat format = NumberFormat.getInstance(locale);
// "10,000" -> 10000L
return format.parse(text);
}
@Override
public String print(Number object, Locale locale) {
log.info("object = {}, locale = {}", object, locale);
// 10000L -> "10,000"
return NumberFormat.getInstance(locale).format(object);
}
}
Integer, Long, Double의 부모 타입parse 결과는 Long으로 반환됨 (테스트에서 확인)✅ 테스트 코드
class PriceFormatterTest {
PriceFormatter formatter = new PriceFormatter();
@Test
void parse() throws ParseException {
Number result = formatter.parse("1,000", Locale.KOREA);
// parse 결과는 Long
Assertions.assertThat(result).isEqualTo(1000L);
}
@Test
void print() {
String result = formatter.print(1000, Locale.KOREA);
Assertions.assertThat(result).isEqualTo("1,000");
}
}
Locale.KOREA 기준으로"1,000" → 1000L1000 → "1,000"📑 흐름 한눈 정리
parse(text, locale) → 객체(Number)print(object, locale) → 출력 문자열🧠 요약 정리
| 구분 | 역할 | 핵심 메서드 | 특징/비고 |
|---|---|---|---|
| Formatter | 문자열 ↔ 객체 변환 (포맷 초점) | print(Object, Locale), parse(String, Locale) | 포맷 제어에 특화 |
| ✍️ Printer | 객체 → 문자열 | print(Object, Locale) | 표시 형식(, . 등) 적용 |
| 🔎 Parser | 문자열 → 객체 | parse(String, Locale) | 포맷 해석 (구분자 제거 등) |
| 🌐 Locale | 지역/언어 정보 | — | 국제화에 따른 표기 방식 결정 |
| 예시(PriceFormatter) | 금액 문자열 ↔ 숫자 | NumberFormat.getInstance(locale) | "1,000" ↔ 1000L |
| Number | 숫자 부모 타입 | — | Integer/Long/Double의 상위 |