문제

PMD 다음에 대한 위반 사항을 신고합니다.

ArrayList<Object> list = new ArrayList<Object>();

위반 사항은 "'ArrayList'와 같은 구현 유형을 사용하지 마십시오.대신 인터페이스를 사용하세요."

다음 줄은 위반 사항을 수정합니다.

List<Object> list = new ArrayList<Object>();

왜 후자를 사용해야합니까? List 대신에 사용 ArrayList?

도움이 되었습니까?

해결책

콘크리트 유형 위에 인터페이스를 사용하는 것이 좋은 캡슐화와 코드를 느슨하게 연결하는 핵심입니다.

자신의 API를 쓸 때이 연습을 따르는 것이 좋습니다. 그렇게한다면 나중에 코드에 단위 테스트를 추가하고 (조롱 기법 사용) 향후 필요한 경우 기본 구현을 변경하는 것이 더 쉽다는 것을 알게 될 것입니다.

여기에 있습니다 좋은 기사 주제에.

도움이되기를 바랍니다!

다른 팁

이는 목록 구현에서 코드를 분리하기 때문에 선호됩니다. 인터페이스를 사용하면 목록에 정의 된 메소드 만 사용하는 한 나머지 코드를 변경하지 않고도이 경우 ArrayList, ArrayList를 다른 목록 구현으로 쉽게 변경할 수 있습니다.

일반적으로 나는 구현에서 인터페이스를 분리하는 것이 좋은 것이며 코드를 더 쉽게 유지 관리할 수 있다는 데 동의합니다.

그러나 고려해야 할 예외가 있습니다.인터페이스를 통해 객체에 액세스하면 코드 속도를 느리게 만드는 추가 간접 계층이 추가됩니다.

관심을 끌기 위해 1백만 길이의 ArrayList에 대해 100억 개의 순차 액세스를 생성하는 실험을 실행했습니다.내 2.4Ghz MacBook에서 List 인터페이스를 통해 ArrayList에 액세스하는 데 평균 2.10초가 걸렸고, ArrayList 유형을 선언할 때는 평균 1.67초가 걸렸습니다.

대규모 목록, 내부 루프 내부 또는 자주 호출되는 함수로 작업하는 경우 이는 고려해야 할 사항입니다.

ArrayList 및 LinkedList는 목록의 두 가지 구현으로 주문 된 항목 모음입니다. 논리적으로 배열 목록이나 링크드 목록을 사용하더라도 중요하지 않으므로 유형을 그 유형을 제한해서는 안됩니다.

이것은 다른 것들 인 Say, Collection 및 List와 대조적입니다 (목록은 정렬, 컬렉션이 의미하지 않습니다).

ArrayList 대신 목록이있는 후자를 사용해야하는 이유는 무엇입니까?

그것은 좋은 연습입니다 : 구현보다는 인터페이스로 프로그램

교체하여 ArrayList ~와 함께 List, 당신은 변경할 수 있습니다 List 비즈니스 사용 사례에 따라 다음과 같이 향후 구현.

List<Object> list = new  LinkedList<Object>(); 
/* Doubly-linked list implementation of the List and Deque interfaces. 
 Implements all optional list operations, and permits all elements (including null).*/

또는

List<Object> list = new  CopyOnWriteArrayList<Object>(); 
/* A thread-safe variant of ArrayList in which all mutative operations
 (add, set, and so on) are implemented by making a fresh copy of the underlying array.*/

또는

List<Object> list = new  Stack<Object>(); 

/* The Stack class represents a last-in-first-out (LIFO) stack of objects.*/

또는

다른 List 특정 구현.

List 인터페이스는 계약 및 특정 구현을 정의합니다 List 변경할 수 있습니다. 이런 식으로, 인터페이스 및 구현이 느슨하게 결합됩니다.

관련 SE 질문 :

"인터페이스로 프로그램"이란 무엇을 의미합니까?

로컬 변수의 경우에도 콘크리트 클래스의 인터페이스를 사용하면 도움이됩니다. 인터페이스 외부에있는 메소드를 호출 한 다음 필요한 경우 목록의 구현을 변경하기가 어렵습니다. 또한 선언에서 가장 구체적인 클래스 또는 인터페이스를 사용하는 것이 가장 좋습니다. 요소 순서가 중요하지 않은 경우 목록 대신 컬렉션을 사용하십시오. 그것은 당신의 코드에 최대 유연성을 제공합니다.

클래스/인터페이스의 속성은 구현에 관계없이 클래스에 사용할 동작 계약을 제공하므로 인터페이스를 통해 노출되어야 합니다.

하지만...

지역 변수 선언에서는 다음과 같이 하는 것이 거의 의미가 없습니다.

public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}

지역 변수인 경우 해당 유형을 사용하세요.여전히 적절한 인터페이스로 암묵적으로 업캐스트할 수 있으며 메서드는 인수에 대한 인터페이스 유형을 허용해야 하지만 지역 변수의 경우 구현이 필요한 경우를 대비해 구현 유형을 컨테이너로 사용하는 것이 합리적입니다. 특정 기능.

일반적으로 코드 라인의 경우 인터페이스를 방해하는 것이 합리적이지 않습니다. 그러나 우리가 API에 대해 이야기하고 있다면 정말 좋은 이유가 있습니다. 나는 작은 수업을 받았습니다

class Counter {
    static int sizeOf(List<?> items) {
        return items.size();
    }
}

이 경우 필요한 인터페이스 사용이 필요합니다. 크기를 계산하고 싶기 때문입니다 가능한 모든 내 자신의 관습을 포함한 구현. class MyList extends AbstractList<String>....

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top