Formattable
Formattable (사용자 정의 형식 인터페이스)
Formatter의 's' 변환 지정자를 사용해 사용자 정의 형식화를 수행해야 하는 모든 클래스가 구현해야 하는 인터페이스예요. 임의 객체를 형식화하기 위한 기본적인 제어를 제공해요.
본문
예를 들어 다음 클래스는 플래그와 길이 제약에 따라 주식 이름을 다르게 출력해요.
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이 던져져요. 코드와 시그니처는 원문 그대로 보존돼요.