[Java] 인터페이스 타입 VS 구현체 타입
List로 선언하고 ArrayList로 초기화하는 거랑, 그냥 처음부터 ArrayList로 선언하는 것의 차이
1. List<String> list = new ArrayList<>(); (권장)
List<String> list = new LinkedList<>();
- 인터페이스 타입(List) 으로 선언하고, 구현체(ArrayList) 로 초기화한 방식
- 다형성(polymorphism) 을 활용한 방식
- 장점: 나중에 ArrayList를 LinkedList, Vector 등으로 바꾸기 쉬움
- 코드가 더 유연하고 유지보수에 유리
- 인터페이스 기반 프로그래밍은 유닛 테스트, 디자인 패턴 적용에도 강함
2. ArrayList<String> list = new ArrayList<>();
- 구현체 자체(ArrayList)로 선언과 초기화를 한 방식
- 장점: ArrayList 고유 기능(예: ensureCapacity)이 필요할 때는 이 방식이 유리
- 단점: ArrayList에 종속되므로, 다른 구현체로 교체하려면 전체 코드 수정이 필요할 수 있음
2.1 ensureCapacity(int minCapacity)
란?
ArrayList
고유 기능 중 대표적인 예시가 ensureCapacity(int minCapacity)
이다.
내부 배열의 용량을 미리 늘려서, 많은 요소를 추가할 때 불필요한 배열 복사를 줄여 성능을 개선해주는 메서드이다.
예를 들면 :
ArrayList<String> list = new ArrayList<>();
list.ensureCapacity(1000); // 내부 배열 크기를 최소 1000으로 미리 확보
for (int i = 0; i < 1000; i++) {
list.add("item " + i);
}
- 기본
ArrayList
는 요소가 추가될 때마다 내부 배열 크기가 꽉 차면 자동으로 크기를 늘리고 기존 데이터를 복사한다. ensureCapacity
를 호출하면, 필요한 만큼 미리 공간을 확보해 두어, 반복적으로 크기를 늘리고 복사하는 비용을 줄여주는 원리이다.- 따라서 대량의 데이터를 추가할 때 성능 최적화가 필요하면
ArrayList
타입으로 선언해서 이 메서드를 직접 쓸 수 있다.
2.2 그 외 고유 기능들
trimToSize()
: 사용하지 않는 여유 공간을 줄여 메모리 사용 최적화clone()
:ArrayList
복제 (얕은 복사)
3. 결론
List<String> list = new ArrayList<>();
로 선언하면 인터페이스 타입이어서ensureCapacity()
같은ArrayList
만의 메서드를 바로 쓸 수 없다. 반면ArrayList<String> list = new ArrayList<>();
로 선언하면 이런 고유 기능들을 직접 활용할 수 있다.
- ✔️ 대부분의 경우 List<String> list = new ArrayList<>();처럼 인터페이스 타입으로 선언하는 것이 더 좋은 습관이다.
- ✔️ 구체 구현체에 종속되지 않고 유연하고 확장 가능한 코드를 작성할 수 있기 때문이다.
출처: chatGPT