[Effective Java] 아이템62 - 다른 타입이 적절하다면 문자열 사용을 피하라

이번 아이템에서는 문자열을 쓰지 않아야 할 사례를 다룬다.

문자열은 다른 값 타입을 대신하기에 적합하지 않다.

받은 데이터가 수치형이라면 int, float, BigEnter 등 적당한 수치타입으로 변환해야한다. 데이터가 진짜 문자열일 때만 문자열을 쓰자.

문자열은 열거 타입을 대신하기에 적합하지 않다.

아이템34에서 이야기 했듯, 상수를 열거할 때는 문자열보다는 열거 타입이 낫다.

혼합 타입을 대신하기에 적합하지 않다.

여러 요소가 혼합된 데이터를 하나의 문자열로 표현한 것은 좋지 않다.

String compoundKey = className + "#" + i.next();

문자열은 권한을 표현하기에 적합하지 않다.

스레드 지역변수를 예로 들어보자. 스레드 지역변수는 각 스레드가 지역변수를 가질수 있는 기능이다. 1개의 스레드를 공유한다면 그 안에서 지역변수들을 공유할 수 있다. 스레디 지역변수에 대한 글은 이 포스팅을 참고했다.

자바 2부터 이 기능을 제공했는데, 스레드를 식별하기 위해서 클라이언트가 문자열 key를 지정해줬었다.

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() {}
  public static class Key {
    Key() {}
  }
  public static Key getKey() {
    return new Key();
  }
  public static void set(Key key, Object value);
  public static Object get(Key key);
}

위 코드는 앞서 문자열 기반 API의 문제를 해결해주지만, 더 개선할 수 있다. Key 는 그 자체가 스레드 지역변수가 된다.

public class ThreadLocal {
  public ThreadLocal();
  public void set(Object value);
  public Object get();
}

이 API에서 get()은 Object 형으로 형변환 해주기 때문에 타입안전하지 않다. 따라서 매개변수화 타입으로 선언하자.

public class ThreadLocal<T> {
  public ThreadLocal();
  public void set(T value);
  public T get();
}

댓글남기기