peaches-book-study / effective-java

이펙티브 자바 3/E
0 stars 2 forks source link

Item 62. 다른 타입이 적절하다면 문자열 사용을 피하라 #59

Open pyeong114 opened 4 months ago

pyeong114 commented 4 months ago

Chapter : 9. 일반적인 프로그래밍 원칙

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

Assignee : pyeong114


🍑 서론

문자열(String)은 텍스트를 표현하도록 설계되었지만, 의도하지 않은 용도로 쓰이는 경향이 있다. 이번 아이템에서는 문자열을 쓰지 않아야 할 사례를 다룸

🍑 본론

문자열을 잘못쓰는 사례


혼합 타입을 문자열로 대신 사용하는 예


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

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

문자열로 권한을 잘못 구분하는 예시


public class ThreadLocal {
  private ThreadLocal() {} // 객체 생성 불가

  // 현 스레드의 값을 키로 구분해 저장한다.
  public static void set(String key, Object value);

  // 현 스레드의 값을 반환한다.
  public static Object get(String key);
}

ThreadLocal? : Java에서 특정 스레드에만 고유하게 데이터를 저장하고 읽을 수 있도록 지원하는 클래스 : 여러 스레드가 동시에 실행되는 환경에서도 각 스레드마다 독립적인 데이터를 갖게 되어 독립적인 작업 가능


public class ThreadLocalExample {
// ThreadLocal 객체 생성
private static final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
    Runnable task1 = () -> {
        threadLocal.set(100); // 각 스레드에 데이터 저장
        System.out.println("Task 1: " + threadLocal.get());
    };

    Runnable task2 = () -> {
        threadLocal.set(200); // 각 스레드에 데이터 저장
        System.out.println("Task 2: " + threadLocal.get());
    };

    // 두 개의 스레드를 생성하여 실행
    Thread thread1 = new Thread(task1);
    Thread thread2 = new Thread(task2);

    thread1.start();
    thread2.start();
}

} // Task 1: 100 // Task 2: 200

```java
public class ThreadLocalExample {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            // 스레드 1에서 각 키에 값을 저장
            ThreadLocal.set("username", "Alice");
            ThreadLocal.set("role", "admin");

            // 저장된 값을 가져와 출력
            System.out.println("Thread 1 - Username: " + ThreadLocal.get("username"));
            System.out.println("Thread 1 - Role: " + ThreadLocal.get("role"));
        };

        Runnable task2 = () -> {
            // 스레드 2에서 다른 값을 저장
            ThreadLocal.set("username", "Bob");
            ThreadLocal.set("role", "user");

            // 저장된 값을 가져와 출력
            System.out.println("Thread 2 - Username: " + ThreadLocal.get("username"));
            System.out.println("Thread 2 - Role: " + ThreadLocal.get("role"));
        };

        // 두 스레드를 생성하여 실행
        Thread thread1 = new Thread(task1);
        Thread thread2 = new Thread(task2);

        thread1.start();
        thread2.start();
    }
}

Key 클래스로 권한을 구분한 예시


public class ThreadLocal {
  private ThreadLocal() {} // 생성자 막기

  // 내부 `Key` 클래스를 이용하여 인스턴스에 무관한 키를 생성할 수 있게 만든다.
  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 문제를 모두 해결할 수 있다.

🍑 결론


Referenced by

pyeong114 commented 4 months ago

https://jake-seo-dev.tistory.com/543