도당탕탕
Item62 : 다른 타입이 적절한곳에 String을 피하라. 본문
보통 파일이나 네트워크로부터 데이터가 넘어오면, String 형태의 데이터인 경우가 많다. 하지만 이를 그대로 String 변수에 저장하기보다 적절한 자료형으로 저장하는 것이 좋다.
String은 aggregate type을 표현하기 에는 부적절하다.
String compoundKey = className + "#" + i.next()
위 처럼 표현하면 결국, className을 뽑아내기 위해서는 String을 파싱 해야 한다.
그보다는 item 24에서 배웠듯이 static class
를 사용해서 표현하는 것이 좋다.
private static class CompoundKey {
String className;
String next;
public CompoundKey(String className, String next) {
this.className = className;
this.next = next;
}
}
문자열은 권한을 표현하기에 적절하지 못하다.
public class ThreadLocal {
private ThreadLocal() {} //객체 생성 불가
// 현 스레드의 값을 키로 구분해 저장한다.
public static void set(String key, Object value);
// (키가 가르키는) 현 스레드의 값을 반환한다.
public static Object get(String key);
}
ThreadLocal 은 하나의 스레드에서 실행되는 코드가 동일한 객체를 사용할 수 있도록 한다. 주요 용도는 아래와 같다.
- 사용자 인증정보 전파 - Spring Security에서는 ThreadLocal을 이용해서 사용자 인증 정보를 전파한다.
- 트랜잭션 컨텍스트 전파 - 트랜잭션 매니저는 트랜잭션 컨텍스트를 전파하는 데 ThreadLocal을 사용한다.
- 쓰레드에 안전해야 하는 데이터 보관
위 방식의 문제점은 두 가지 문제점이 있다.
- 여러 클라이언트가 같은 String을 key로 사용할 수 있어서, 에러를 발생시킬 수 있다.
- 보안상, malicious client가 의도적으로 다른 클라이언트와 같은 String을 전달해서, 데이터를 엿볼 수 있다.
이를 계선하기 위해서 Key라는
클래스를 생성한다.
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);
}
이 시점에 top-level 클래스는 아무 기능을 해주지 못하므로, nested class를 ThreadLocal
로 이름을 변경할 수 있다.
public final class ThreadLocal {
public ThreadLocal();
public void set(Object value);
public Object get();
}
이렇게 하면 Key는 더 이상 스레드 지역변수를 구분하기 위한 키가 아니라 그 자체가 스레드 지역변수가 된다.
이 API는 get으로 얻은 Object를 실제 타입으로 타입 캐스팅 해야 해서 타입안전하지 않다.
이를 제너릭으로 타입 안전하게 만들 수 있다.
public final class ThreadLocal<T> {
public ThreadLocal();
public void set(T value);
public T get();
}
정리
- 더 적합한 데이터 타입이 있거나 새로 작성할 수 있다면, 문자열을 쓰지 말자
- 문자열은 잘못 사용하면 번거롭고, 덜 유연하고, 느리고 오류 가능성도 크다.
- 문자열을 잘못 사용하는 흔한 예로는 기본 타입, 열거 타입, 혼합 타입이 있다.
'JAVA' 카테고리의 다른 글
Item64 : 인터페이스로 객체들을 참조하라. (0) | 2023.01.17 |
---|---|
Item63 : 문자열 연결은 느리니 주의하라 (0) | 2023.01.17 |
Item61 : 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2023.01.16 |
Item60 : 정확한 답이 요구되지 않으면, FLOAT와 DOUBLE을 피하라. (0) | 2023.01.13 |
Item59 : 라이브러리를 익히고 사용하라 (0) | 2023.01.13 |
Comments