본문 바로가기
Language/Java

[JAVA] Arrays.asList() vs new ArrayList() : 단순 변환과 새로운 생성의 결정적 차이

by Papa Martino V 2026. 1. 18.
728x90

Arrays.asList() vs new ArrayList()
Arrays.asList() vs new ArrayList()

 

자바 개발을 하다 보면 배열을 리스트로 변환해야 하는 상황을 수없이 마주하게 됩니다. 이때 가장 흔히 사용하는 방식이 Arrays.asList()입니다. 하지만 어떤 경우에는 이 리스트에 데이터를 추가하려고 할 때 UnsupportedOperationException 에러를 만나 당황하기도 합니다. 반면 new ArrayList<>() 생성자를 이용하는 방식은 훨씬 자유로워 보입니다. 오늘은 이 두 방식의 메모리 구조적 차이가변성(Mutability)에 대해 심층적으로 파헤쳐 보겠습니다.

1. Arrays.asList(): "배열의 리스트 뷰(View)"

Arrays.asList()는 엄밀히 말해 새로운 리스트 객체를 완전히 독립적으로 생성하는 것이 아닙니다. 원본 배열을 '리스트라는 안경'으로 바라보게 해주는 어댑터(Adapter) 역할을 수행합니다.

핵심 메커니즘

  • 고정 크기: 반환된 리스트는 원본 배열과 동일한 크기를 유지해야 합니다. 따라서 add()remove()처럼 크기를 변경하는 작업은 불가능합니다.
  • 메모리 공유: 리스트의 요소를 수정하면 원본 배열의 데이터도 함께 변합니다. 반대로 배열을 수정하면 리스트의 내용도 변합니다. 이는 두 객체가 동일한 데이터 주소를 참조하기 때문입니다.
  • 클래스 타입: 이 메서드가 반환하는 클래스는 java.util.ArrayList가 아니라, java.util.Arrays 내부의 중첩 클래스인 별도의 ArrayList입니다.

2. new ArrayList<>(Arrays.asList()): "완전한 독립과 자유"

배열을 기반으로 하되, 원본과는 아무런 상관이 없는 새로운 리스트를 만들고 싶다면 생성자를 이용해야 합니다. 이는 원본 배열의 데이터를 모두 복사하여 메모리의 새로운 영역에 독립적인 저장소를 구성하는 방식입니다.

핵심 메커니즘

  • 가변성 보장: 데이터를 추가하거나 삭제하는 모든 리스트 작업을 자유롭게 수행할 수 있습니다.
  • 독립성: 생성 이후에는 원본 배열의 값이 변하더라도 리스트에는 아무런 영향을 주지 않습니다.
  • 표준 구현체: 우리가 흔히 알고 있는 java.util.ArrayList 객체로 동작합니다.

3. 한눈에 비교하는 차이점 정리

두 방식의 차이를 인지하지 못하고 코드를 작성하면 런타임 에러나 예상치 못한 데이터 변조 버그를 유발할 수 있습니다. 아래 표를 통해 명확히 비교해 보세요.

항목 Arrays.asList(arr) new ArrayList<>(Arrays.asList(arr))
구조적 특징 원본 배열의 "뷰(View)" 제공 원본 데이터를 "복사(Copy)"하여 생성
크기 변경 (add/remove) 불가능 (Exception 발생) 가능
요소 수정 (set) 가능 (원본 배열도 함께 변함) 가능 (리스트만 변함)
메모리 참조 원본 배열의 메모리를 공유 별도의 힙(Heap) 메모리 할당
주요 용도 고정된 데이터를 빠르게 리스트화할 때 데이터 가공이 필요한 동적 리스트가 필요할 때

4. 개발 시 주의해야 할 성능 및 설계 팁

단순히 읽기 전용으로 리스트를 사용한다면 Arrays.asList()가 더 효율적입니다. 추가적인 메모리 복사 과정이 없기 때문입니다. 하지만 리스트를 반환값으로 넘겨줄 때, 받는 쪽에서 데이터를 수정할 가능성이 있다면 반드시 new ArrayList<>()로 감싸서 넘겨주는 방어적 복사(Defensive Copy) 전략이 필요합니다. 특히 자바 9 이후부터는 고정된 리스트를 만들 때 List.of()라는 더 현대적인 대안이 등장했습니다. List.of()Arrays.asList()와 달리 요소의 수정조차 허용하지 않는 완전 불변(Immutable) 리스트를 반환하므로, 의도치 않은 부수 효과를 방지하는 데 더 유리합니다.

5. 결론: 선택의 기준

질문의 답은 여러분의 '의도'에 달려 있습니다. 원본 배열과 연결된 채로 리스트의 인터페이스만 빌려 쓰고 싶다면 Arrays.asList()를, 원본으로부터 독립하여 자유롭게 데이터를 편집하고 싶다면 new ArrayList<>()를 선택하십시오. 이 작은 차이가 시스템의 안정성과 데이터 무결성을 결정짓는 중요한 열쇠가 됩니다.


내용 출처 및 참고 문헌

  • Oracle Java Standard Edition Documentation: java.util.Arrays.asList()
  • Oracle Java Standard Edition Documentation: java.util.ArrayList
  • Effective Java, 3rd Edition by Joshua Bloch: Item 50: Make defensive copies when needed
  • OpenJDK Source Code Analysis: java.util.Arrays.InternalArrayList implementation
728x90