문자열은 다른 값 타입을 대신하기에 적합하지 않다.
String compoundKey = className + "#" + i.next();
이렇게 사용할 경우 단점이 많다.
그러므로 전용 클래스를 새로 만들자. 보통 private 정적 멤버 클래스로 선언한다.
문자열은 권한을 표현하기에 적합하지 않다.
권한(capacity)을 문자열로 표현하는 경우가 종종 있다.
예를 들어 스레드 지역변수 기능(각 스레드가 자신만의 변수를 갖게 해주는 기능)을 설계한다고 해보자. (자바가 이 기능을 지원하기 시작한 것은 자바 2부터다. 그 전에는 프로그래머가 직접 구현해야 했다.) 이때 클라이언트가 제공한 문자열 키로 스레드별 지역변수를 식별하도록 해보자.
public class ThreadLocal() {
private ThreadLocal() {} // 객체 생성 불가
// 현 스레드의 값을 키로 구분해 저장한다.
public static void set(String key, Object value);
// (키가 가리키는) 현 스레드의 값을 반환한다.
public static Object get(String key);
}
이 방식의 문제는 스레드 구분용 문자열 키가 전역 이름공간에 공유된다는 점이다.
이 방식대로 하면, 서로 다른 클라이언트가 동일한 키를 사용할 경우 제대로 동작하지 못한다.
문제를 해결하려면 문자열 대신 위조할 수 없는 키를 사용하면 된다. 이 키를 권한(capacity)라고 한다.
public class ThreadLocal {
private ThreadLocal() {} // 객체 생성 불가
private static class Key { // 권한
Key() {}
}
public static void set(Key key, Object value);
public static Object get(Key key);
}
이제는 위의 코드를 좀 더 개선해보자.
public final class ThreadLocal<T> {
public ThreadLocal();
public void set(T value);
public T get();
}
이제 자바의 java.lang.ThreadLocal과 흡사해졌다.
문자열 기반 API의 문제를 해결해주며, 키 기반의 API보다 빠르고 우아하다.
📌 핵심 정리
더 적합한 데이터 타입이 있거나 새로 작성할 수 있다면, 문자열을 쓰고 싶은 유혹을 뿌리쳐라.
문자열은 잘못 사용하면 번거롭고, 덜 유연하고, 느리고, 오류 가능성도 크다.
문자열을 잘못 사용하는 흔한 예로는 기본 타입, 열거 타입, 혼합 타입이 있다.