Formattable

Formattable (사용자 정의 형식 인터페이스)

Formatter's' 변환 지정자를 사용해 사용자 정의 형식화를 수행해야 하는 모든 클래스가 구현해야 하는 인터페이스예요. 임의 객체를 형식화하기 위한 기본적인 제어를 제공해요.

출처: Java API Reference

본문

예를 들어 다음 클래스는 플래그와 길이 제약에 따라 주식 이름을 다르게 출력해요.

import java.nio.CharBuffer;
import java.util.Formatter;
import java.util.Formattable;
import java.util.Locale;
import static java.util.FormattableFlags.*;

public class StockName implements Formattable {
    private String symbol, companyName, frenchCompanyName;
    public StockName(String symbol, String companyName, String frenchCompanyName) { ... }

    public void formatTo(Formatter fmt, int f, int width, int precision) {
        StringBuilder sb = new StringBuilder();
        String name = companyName;
        if (fmt.locale().equals(Locale.FRANCE)) name = frenchCompanyName;
        boolean alternate = (f & ALTERNATE) == ALTERNATE;
        boolean usesymbol = alternate || (precision != -1 && precision < 10);
        String out = (usesymbol ? symbol : name);
        if (precision == -1 || out.length() < precision) {
            sb.append(out);
        } else {
            sb.append(out.substring(0, precision - 1)).append('*');
        }
        int len = sb.length();
        if (len < width)
            for (int i = 0; i < width - len; i++)
                if ((f & LEFT_JUSTIFY) == LEFT_JUSTIFY) sb.append(' ');
                else sb.insert(0, ' ');
        fmt.format(sb.toString());
    }

    public String toString() { return String.format("%s - %s", symbol, companyName); }
}

Formatter와 함께 사용하면 위 클래스는 다양한 형식 문자열에 대해 다음과 같은 출력을 만들어요.

Formatter fmt = new Formatter();
StockName sn = new StockName("HUGE", "Huge Fruit, Inc.", "Fruit Titanesque, Inc.");
fmt.format("%s", sn);        // -> "Huge Fruit, Inc."
fmt.format("%s", sn.toString()); // -> "HUGE - Huge Fruit, Inc."
fmt.format("%#s", sn);       // -> "HUGE"
fmt.format("%-10.8s", sn);   // -> "HUGE      "
fmt.format("%.12s", sn);     // -> "Huge Fruit,*"
fmt.format(Locale.FRANCE, "%25s", sn); // -> "  Fruit Titanesque, Inc."

Formattable은 반드시 멀티쓰레드에 안전한 것은 아니에요. 쓰레드 안전성은 선택 사항이며 이 인터페이스를 확장·구현하는 클래스가 강제할 수 있어요. 이 인터페이스의 메서드에 null 인자를 넘기면 명시되지 않은 경우 NullPointerException이 던져져요. 코드와 시그니처는 원문 그대로 보존돼요.

더 알아보기