반응형
1. 우리가 보는 것은 이것뿐이다.
List<String> list = List.of("A", "B");
우리는
List
를 받는다고만 생각한다.
2. 그런데 List는 인터페이스다.
public interface List<E> {
...
}
인터페이스는 객체를 만들 수 없다.
new List<>(); // 컴파일 에러
즉,
List.of(...)
는 내부에서 반드시 어떤 구현체를 생성해서 반환해야 한다.
3. 내부에서는 이런 식으로 동작한다. (개념적으로)
public static <E> List<E> of(E... elements) {
if (elements.length == 0) {
return new List0<>();
}
if (elements.length == 1) {
return new List1<>(elements[0]);
}
if (elements.length == 2) {
return new List12<>(elements[0], elements[1]);
}
return new ListN<>(elements);
}
실제 JDK 코드도 거의 이런 구조다.
4. 왜 굳이 여러 클래스를 만들었을까?
예를 들어
원소가 1개인 경우
List<String> list = List.of("A");
굳이
Object[] array = new Object[1];
를 만들 필요가 없다.
그냥
class List1 {
Object e0;
}
이 메모리를 더 적게 사용한다.
원소가 2개인 경우
List.of("A", "B");
는
class List12 {
Object e0;
Object e1;
}
처럼 저장하면 배열을 만들지 않아도 된다.
원소가 많으면
List.of("A", "B", "C", "D");
이건 개수를 알 수 없으므로
class ListN {
Object[] elements;
}
를 사용한다.
5. 실제로 확인해보면
List<String> list1 = List.of();
List<String> list2 = List.of("A");
List<String> list3 = List.of("A", "B");
List<String> list4 = List.of("A", "B", "C");
System.out.println(list1.getClass());
System.out.println(list2.getClass());
System.out.println(list3.getClass());
System.out.println(list4.getClass());
출력(Java 버전에 따라 조금 다를 수 있음)
class java.util.ImmutableCollections$ListN
class java.util.ImmutableCollections$List12
class java.util.ImmutableCollections$List12
class java.util.ImmutableCollections$ListN
6. 그럼 왜 내가 신경 안 써도 되는데?
내 코드는
List<String> list = List.of("A", "B");
뿐이다.
나는
ArrayList인지?
LinkedList인지?
List12인지?
ListN인지?
알 필요가 없다.
왜냐하면
list.get(0);
list.size();
list.contains("A");
같은 List 인터페이스만 사용하면 되기 때문이다.
7. 만약 생성자를 썼다면?
예를 들어
ArrayList<String> list = new ArrayList<>();
라고 하면
나는 이미
ArrayList
라는 구현체에 의존하게 된다.
JDK가
더 좋은 구현체가 있으니 이걸 써라
라고 해도 내 코드는 바뀌어야 한다.
8. Static Factory Method가 좋은 이유가 여기서 나온다.
List<String> list = List.of(...);
만 호출하면
JDK 개발자는 내부에서
Java 9 : List12 사용
Java 17 : List12 개선
Java 21 : 더 빠른 ListX 개발
Java 25 : 완전히 새로운 구현체
로 얼마든지 변경할 수 있다.
하지만 사용자 코드는
List<String> list = List.of(...);
한 줄도 수정할 필요가 없다.
핵심 한 줄
Static Factory Method의 "구현체를 숨긴다"는 의미는 "사용자는 List라는 인터페이스만 알고, 실제 반환되는 객체(List12, ListN, ArrayList, ImmutableList 등)는 라이브러리 작성자가 자유롭게 선택하고 변경할 수 있다"는 뜻이다.
즉,
List<String> list = List.of("A", "B");
에서 list의 컴파일 타입은 List이고, 런타임 실제 객체 타입은 JDK가 선택한 내부 구현체인 것이다.
반응형
'language > java' 카테고리의 다른 글
| 번외편 - Java Comparator vs JavaScript sort() (0) | 2026.06.04 |
|---|---|
| Factory Method Pattern과 Strategy Pattern 비교 (0) | 2026.06.01 |
| Factory Method Pattern (팩토리 메서드 패턴) (0) | 2026.06.01 |
| Static Factory Method (정적 팩토리 메서드) (0) | 2026.06.01 |
| Virtual Thread (Java 21) 완벽 이해하기 (0) | 2026.06.01 |
댓글