Enumeration이 java.utils의 List가 아닌 ArrayList로 변환되는 이유는 무엇입니까?
패키지 의 Collections.list () 메서드 java.utils
가 ArrayList<T>
대신 List<T>
?를 반환하는 좋은 이유가 있습니까?
분명히이 ArrayList
A는 List
,하지만 난 그것을 구현 유형 대신 인터페이스 형식을 반환하는 일반적으로 좋은 연습이 있다는 인상입니다.
면책 조항 : 저는 JDK 작성자가 아닙니다.
인터페이스에 자신의 코드 를 작성하는 것이 옳다는 데 동의 하지만 변경 가능한 컬렉션을 제 3 자에게 반환하려는 경우 제 3 자에게 어떤 종류 의 코드 가 반환되는지 알려주는 것이 중요합니다 List
.
LinkedList
및 ArrayList
다양한 작업을 위해, 현명 성능, 매우 다릅니다. 예를 들어,의 첫 번째 요소를 제거하는 ArrayList
것은 O(n)
이지만 a의 첫 번째 요소를 제거하는 LinkedList
것은 O(1)
입니다.
반환 유형을 완전히 지정함으로써 JDK 작성자는 어떤 종류의 객체를 반환하는지에 대한 명확한 코드로 추가 정보를 전달 하므로이 메서드를 올바르게 사용하도록 코드를 작성할 수 있습니다. 정말 필요한 경우 LinkedList
여기에 지정해야합니다.
마지막으로, 구현을 통해 인터페이스를 코딩하는 주된 이유는 구현이 변경 될 것이라고 생각하는 경우입니다. JDK 작성자는 이 방법을 절대로 변경 하지 않을 것이라고 생각할 것입니다 . LinkedList
또는 a 를 반환하지 않습니다 Collections.UnmodifiableList
. 그러나 대부분의 경우 다음을 수행 할 수 있습니다.
List<T> list = Collections.list(enumeration);
를 반환하면 프로그램을 인터페이스List
로 승격하게 됩니다 . 이는 매우 좋은 방법입니다. 그러나이 접근법에는 한계가 있습니다. 예를 들어 인터페이스 ArrayList
에 정의되어 있고 존재하지 않는 일부 메서드를 사용할 수 없습니다 . 자세한 내용 List
은 이 답변 을 참조하십시오.
Java ™ 튜토리얼에서 API 디자인 을 인용하고 있습니다 .
... 컬렉션 인터페이스 중 하나 를 구현 하거나 확장 하는 모든 유형 의 개체를 반환하는 것이 좋습니다. 이는 인터페이스 중 하나이거나 이러한 인터페이스 중 하나를 확장하거나 구현하는 특수 목적 유형일 수 있습니다.
.. 어떤 의미에서 반환 값은 입력 매개 변수의 반대 동작을 가져야합니다 . 가장 일반적인 .. 보다는 가장 구체적인 적용 가능한 컬렉션 인터페이스 를 반환하는 것이 가장 좋습니다 . 예를 들어 항상를 반환 할 것이라고 확신하는 경우 관련 메서드에 . 이 아닌 반환 유형을 지정해야합니다 . 인스턴스는 일반 인스턴스 보다 빌드하는 데 더 많은 시간이 소요되며 더 강력합니다. 모듈이을 빌드하는 데 이미 시간을 투자 했으므로 사용자에게 향상된 성능에 대한 액세스 권한을 부여하는 것이 좋습니다. 또한 사용자는 반환 된 객체를 a를 요구하는 메소드 와 .
SortedMap
SortedMap
Map
SortedMap
Map
SortedMap
SortedMap
Map
ArrayList
본질적으로 배열 이기 때문에 "컬렉션 배열"이 필요할 때 첫 번째 선택입니다. 따라서 열거 형을 목록으로 변환하려면 배열 목록을 선택합니다.
다른 경우에도 다음과 같이 작성하는 것이 유효합니다.
List<T> list = Collections.list(e);
새로 생성 된 가변 객체의 "배타적 소유권"을 반환하는 함수는 종종 가장 구체적인 유형이 실용적이어야합니다. 불변 객체를 반환하는 객체, 특히 공유 될 수있는 경우에는 종종 덜 구체적인 유형을 반환해야합니다.
구별되는 이유는 전자의 경우 객체가 항상 지정된 유형의 새 객체를 생성 할 수 있고 수신자가 객체를 소유하고 수신자가 수행하려는 작업을 말할 수 없기 때문입니다. 일반적으로 객체를 반환하는 코드가 대체 인터페이스 구현이 수신자의 요구를 충족 할 수 있는지 여부를 알 수있는 방법이 아닙니다.
후자의 경우 객체가 불변이라는 사실은 함수가 정확한 내용을 고려 하여 더 복잡한 유형이 할 수있는 모든 작업을 수행 할 수있는 대체 유형을 식별 할 수 있음을 의미합니다 . 예를 들어 Immutable2dMatrix
인터페이스는 ImmutableArrayBacked2dMatrix
클래스와 클래스에 의해 구현 될 수 있습니다 ImmutableDiagonal2dMatrix
. 정사각형을 반환해야하는 함수 는 주 대각선의 모든 요소가 0이면 인스턴스 Immutable2dMatrix
를 반환할지 ImmutableDiagonalMatrix
아니면 그렇지 않으면를 반환할지 결정할 수 있습니다 ImmutableArrayBackedMatrix
. 전자 유형은 저장 공간을 훨씬 적게 차지하지만받는 사람은 그 차이에 대해 신경 쓰지 않아야합니다.
Immutable2dMatrix
구체적이 아니라 반환 ImmutableArrayBackedMatrix
하면 코드가 배열에 포함 된 내용을 기반으로 반환 유형을 선택할 수 있습니다. 또한 배열을 반환해야하는 코드가 적절한 구현을 보유하고 Immutable2dMatrix
있는 경우 새 인스턴스를 생성하지 않고 간단히 반환 할 수 있습니다. 이 두 가지 요소는 불변 객체로 작업 할 때 주요 "승리"가 될 수 있습니다.
그러나 변경 가능한 객체로 작업 할 때는 두 요소 모두 작동하지 않습니다. 가변 배열이 생성 될 때 주 대각선을 벗어나는 요소가 없을 수 있다는 사실은 그러한 요소가 전혀 없다는 것을 의미하지 않습니다. 결과적으로 an ImmutableDiagonalMatrix
은의 하위 유형 Immutable2dMatrix
이지만 a MutableDiagonalMatrix
는 a의 하위 유형이 아닙니다. Mutable2dMatrix
왜냐하면 후자는 주 대각선에서 상점을받을 수있는 반면 전자는 허용하지 않기 때문입니다. 또한 변경 불가능한 객체는 공유 할 수 있고 공유해야하는 경우가 많지만 일반적으로 공유 할 수 없습니다. 특정 콘텐츠로 초기화 된 새 변경 가능한 컬렉션을 요청하는 함수는 백업 저장소가 요청 된 유형과 일치하는지 여부에 관계없이 새 컬렉션을 만들어야합니다.
객체에서 직접 호출하기보다는 인터페이스에서 var 메서드를 호출 할 때 약간의 오버 헤드가 있습니다.
이 오버 헤드는 종종 1 개 또는 2 개의 프로세서 명령어를 넘지 않습니다. 메서드 호출의 오버 헤드는 JIT가 메서드가 최종임을 알면 훨씬 더 낮습니다. 이것은 대부분의 코드에서 측정 할 수 없지만 java.utils의 저수준 메서드의 경우 문제가되는 일부 코드에서 사용할 수 있습니다.
또한 다른 답변에서 지적했듯이 반환되는 객체의 구체적인 유형 (인터페이스 뒤에 숨겨져 있더라도)은 그것을 사용하는 코드의 성능에 영향을 미칩니다. 이러한 성능 변화는 매우 클 수 있으므로 호출 소프트웨어가 작동하지 않을 정도입니다.
분명히 작성자는 java.utils
Collections.list ()를 호출하는 모든 소프트웨어가 결과로 무엇을하는지 알 수있는 방법이 없으며 Collections.list () 이식을 변경하는 경우이 소프트웨어를 다시 테스트 할 방법이 없습니다. 따라서 유형 시스템이 허용하더라도 다른 유형의 List를 반환하기 위해 Collections.list () 이식을 변경하지 않을 것입니다!
자신의 소프트웨어를 작성할 때 모든 코드를 포괄하는 자동화 된 테스트가 있고 코드가 상호 관계되는 방식을 잘 이해하고 성능이 문제가되는 부분을 알 수 있습니다. 호출자를 변경하지 않고도 메서드를 변경할 수 있다는 것은 소프트웨어 디자인이 변경되는 동안 큰 가치가 있습니다.
따라서 두 가지 상충 관계는 매우 다릅니다.
'developer tip' 카테고리의 다른 글
페이지가 완전히로드 될 때까지 브라우저가 페이지를 표시 할 때까지 기다리도록하려면 어떻게해야합니까? (0) | 2020.10.22 |
---|---|
div 요소의 크기 조정 (0) | 2020.10.22 |
최대 절전 양방향 매핑으로 인한 json serializer의 순환 참조를 해결하는 방법은 무엇입니까? (0) | 2020.10.22 |
스 와이프를 활성화하여 TableView에서 셀을 삭제하는 방법은 무엇입니까? (0) | 2020.10.21 |
symfony2 애플리케이션의 Angularjs (0) | 2020.10.21 |