#50 다른 타입을 쓸 수 있는 곳에서는 String 사용을 피하자
String은 텍스트를 나타내기 위해 설계되었습니다.
이 String으로 해서는 안 되는 것들에 대해 알아보겠습니다.
기본형이나 객체 참조 중 적합한 타입이 있으면, 그 타입을 이용해야 한다는 당연한 얘기입니다.
ex) String index = "0"; -> int index = 0;
열거형 상수는 String 보다 enum을 이용해 만드는 것이 더 좋습니다.
https://brunch.co.kr/@oemilk/147
만약 여러 개의 컴포넌트들을 갖는 경우엔 하나의 String으로 표현하는 것은 좋지 않습니다.
// String을 집합 타입에 잘못 이용한 경우
String compoundKey = className + "#" + i.next();
이런 식으로 컴포넌트들을 하나의 String으로 표현했을 경우에 몇 가지 문제가 발생할 수 있습니다.
우선 각 필드를 구분하는 문자("#")가 컴포넌트 중 하나의 값("#")으로 나오면, 이를 이용한 컴포넌트 분석에 문제가 발생합니다.
그리고 equals, toString, compareTo 메서드도 오버 라이딩이 힘들어집니다.
따라서 집합체를 나타내는 클래스를 별도로 작성하는 게 더 좋습니다.
여기서 말하는 역량(capabilities)란 어떤 기능에 접근하는 권한을 부여하는 것을 말합니다.
예를 들어, 스레드의 지역 변수 관리 체계를 설계할 때 String 값이 스레드 지역 변수를 식별하는데 이용할 수 있습니다.
여기서 문제는 String 값을 Key로 이용하기 때문에, 만약 여러 스레드에서 동일한 Key를 이용한다면 하나의 변수를 공유하게 되므로 보안적으로 허술해집니다.
따라서 String Key 값이 중복되면 안 됩니다.
String Key 값을 위조 불가능한 Key(역량)로 변경하여 이 문제를 해결할 수 있습니다.
다시 수정해서, 아래와 같이 static 메서드들을 없애고 inner class들을 없앨 수 있습니다.
하지만 이는 Object 타입을 그 값의 실제 타입으로 캐스팅해야 하기 때문에, 안전하지 않습니다.
Object 타입을 제네릭을 이용하면, 타입 캐스팅으로 인한 문제를 해결할 수 있습니다.
실제로 이러한 클래스를 java.lang.ThreadLocal 클래스를 통해 제공하고 있습니다.
이처럼 더 좋은 데이터 타입이 있다면, String이 아닌 해당 타입을 이용하는 게 좋습니다.