문자열은 널리 사용되며 자바에서 잘 지원되기 때문에, 일반적으로 텍스트 표현 이외의 다른 용도로도 자주 사용됩니다.
이번 아이템에서는 문자열을 쓰지 않아야 할 사례를 다루겠습니다.
- 문자열은 다른 값 타입을 대신하기에 적합하지 않음
- 문자열은 열거 타입을 대신하기에 적합하지 않음
- 문자열은 혼합 타입을 대신하기에 적합하지 않음
- 문자열은 권한을 표현하기에 적합하지 않음
1. 문자열은 다른 값 타입을 대신하기에 적합하지 않음
- 많은 개발자들이 파일, 네트워크, 키보드 입력으로부터 데이터를 받을 때 주로 문자열을 이용
- 하지만 입력받을 데이터가 진짜 문자열인 경우 즉, 텍스트일 때만 문자열을 사용하는 것을 권장
- 데이터가 수치형이면 int, long, double 등 수치에 적합한 타입을 사용
- `Yes/No`와 같은 질문의 답이라면 적절한 enum 타입 혹은 boolean을 사용
- 정리하자면 문자열은 텍스트 데이터를 다룰 때에만 사용하고, 다른 종류의 데이터는 적절한 값 타입을 사용하여 처리하는 것이 권장
2. 문자열은 열거 타입을 대신하기에 적합하지 않음
- 아이템 34에서 다루었다시피 상수를 열거할 경우에는 문자열 열거 패턴 클래스보다 enum 타입이 훨씬 나음
2.1 문자열 열거 패턴 클래스
2.2 열거 타입
3. 문자열은 혼합 타입을 대신하기에 적합하지 않음
- 여러 요소가 혼합된 데이터를 하나의 문자열로 표현하는 것은 대체로 좋지 않음
코드 부연 설명
- i.next()에 구분자로 사용한 '#' 문자가 있는 경우 혼란스러운 결과가 발생
- 각 요소를 개별적으로 접근하기 위해서 특정 기준을 통해 문자열을 파싱해야 해서 느리고, 귀찮고, 오류 가능성도 큼
- 차라리 전용 클래스를 새로 만들어서 각 데이터 별로 멤버 변수를 취하는 것을 권장
4. 문자열은 권한을 표현하기에 적합하지 않음
- 다음과 같이 권한(capacity)를 문자열로 표현하는 경우가 종종 있음
4.1 문자열을 사용하여 권한을 구분한 잘 못된 예
잘 못된 이유
- 쓰레드 구분용 문자열 키가 전역 변수에 공유됨
- 위 방식이 의도대로 동작하기 위해서는 각 클라이언트가 고유한 키를 제공해야 함
- 만약 ThreadLocal을 사용하는 클라이언트들끼리 합의가 되지 않은 상태로 동일한 키를 사용한다면 의도치 않게 같은 변수를 공유하게 되어 제대로 작동도 안 할뿐더러 보안에도 취약
4.2 별도의 타입으로 권한을 구분하여 해결한 예
개선 포인트
- 앞서의 문자열 기반 API의 문제점을 해결해주지만 개선 포인트 존재
- set/get 메서드는 더 이상 정적 메서드일 필요가 없기 때문에 Key의 인스턴스 메서드로 변경하는 것을 권장
- 위와 같이 처리시 Key는 더 이상 쓰레드 지역변수를 구분하기 위한 Key가 아니라 그 자체가 쓰레드 지역 변수가 됨
4.3 개선된 예
결과적으로 지금의 top level 클래스인 ThreadLocal은 별달리 하는 일이 없어지므로 치워버리고, 중첩 클래스 Key 클래스명을 ThreadLocal로 변경했습니다.
개선 포인트
- 위 API는 get으로 얻은 Object를 실제 타입으로 타입 캐스팅 해야하기 때문에 type-safe 하지 않음
4.4 최종 버전
제네릭을 사용하면 type-safe하게 처리 가능합니다.
정리
- 더 적합한 데이터 타입이 있거나 새로 작성할 수 있는 경우 문자열을 사용하지 말자
- 문자열을 잘 못 사용할 경우 번거롭고, 유연하지 않으며, 느리고 오류 발생 가능성이 크기 때문
참고
이펙티브 자바
반응형
'JAVA > Effective Java' 카테고리의 다른 글
[아이템 64] 객체는 인터페이스를 사용해 참조하라 (0) | 2024.03.18 |
---|---|
[아이템 63] 문자열 연결은 느리니 주의하라 (2) | 2024.03.17 |
[아이템 61] 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2024.03.17 |
[아이템 60] 정확한 답이 필요하다면 float와 double은 피하라 (0) | 2024.03.17 |
[아이템 59] 라이브러리를 익히고 사용하라 (0) | 2024.03.17 |