Skip to content

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

@DongLee99

Description

@DongLee99

다른 타입이 적절하다면 문자열 사용을 피하라

문자열(String)은 텍스트를 표현하도록 설계되었다. 이번 아이템에서는 문자열을 쓰지 않아야 할 사례를 다룬다.

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

다수의 사람들이 파일, 네트워크, 키보드 입력으로 부터 데이터를 받을 때 문자열을 사용한다. 이는 자연스럽다 생각할 수 있지만 그렇지 않다. 입력받을 데이터가 진짜 문자열일 때만 그렇게 하는 것이 좋다. 만약 데이터가 수치형이라면 int, float, BigInteger 등 적당한 수치타입으로 변환해야 한다.

즉 기본 타입이든 참조 타입이든 적절한 값이 있다면 그것을 사용하고, 그렇지 않다면 새로 하나 작성하라.

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

문자열은 혼합 타입을 대신하기에 적합하지 않다. (여러 요소가 혼합된 데이터를 하나의 문자열로 표현하는 것은 옳지 않다)

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

위 코드는 className과 i.next() 부분을 개별로 접근하려면 문자열을 따로 파싱해야 하고 이는 성능 저하와 오류 가능성을 높힌다. 또 적절한 equals, toString, compareTo 메서드를 제공할 수 없으며 String 메소드에 의존하게 된다.

따라서 이런 경우에는 전용 클래스를 생성하자. (private 정적 멤버 클래스)

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

스레드 지역변수 기능을 설계한다고 생각해보자. 이는 스레드가 자신만의 변수를 갖게 해주는 기능이다.

// 잘못된 예 (문자열을 사용해 권한 부여)
public class ThreadLocal {
    private ThreadLocal() {} // 객체 생성 불가 
    public static void set(String key, Object value); // 현 스레드의 값을 키로 구분해 저장
    public static Object get(String Key); // 키가 가르키는 현 스레드의 값 반환
}

문제점

  • 스레드 구분용 문자열 키가 전역 이름공간에서 공유됨 (의도대로 동작하려면 클라이언트가 고유한 키를 제공해야 하는데 클라이언트가 그렇지 않다면 의도치 않게 같은 변수를 공유하게 된다.)
// 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);
}

이는 앞의 문제를 해결해주지만 개선의 여지가 있다. set과 get이 더이상 정적 메서드일 이유가 없으니 Key 클래스의 인스턴스 메서드로 바꾸자.
이렇게 하면 ThreadLocal의 역할이 불분명해지므로 다음과 같이 개선할 수 있다.

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

이 코드 또한 Object를 실제 타입으로 형변환해 써야 하므로 타입 안전하지 않다. 따라서 다음과 같이 개선하면 이 문제까지 해결 가능하다.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions