Pergunta

PMD iria denunciar uma violação para:

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

A violação foi "Evite o uso de tipos de implementação como 'ArrayList'; usar a interface em vez"

.

A seguinte linha iria corrigir a violação:

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

Por que o último com List ser usado em vez de ArrayList?

Foi útil?

Solução

Usando interfaces mais tipos de concreto é a chave para o bom encapsulamento e para solto acoplamento seu código.

É ainda uma boa idéia seguir essa prática ao escrever suas próprias APIs. Se fizer isso, você vai descobrir mais tarde que é mais fácil para adicionar testes de unidade para o código (usando técnicas de zombaria), e de alterar a implementação subjacente, se necessário no futuro.

Aqui está um bom artigo na assunto.

Espero que ajude!

Outras dicas

Este é o preferido porque você dissociar o código a partir da implementação da lista. Usando a interface permite que você facilmente alterar a implementação, ArrayList, neste caso, a outra implementação lista sem alterar qualquer parte do resto do código, desde que ele só usa métodos definidos na lista.

Em geral eu concordo que a dissociação interface da implementação é uma coisa boa e vai fazer seu código mais fácil de manter.

Há, no entanto, exceções que você deve considerar. Acessando objetos por meio de interfaces acrescenta uma camada adicional de engano que vai fazer seu código mais lento.

Para interesse Corri um experimento que gerou dez bilhões de acessos seqüenciais para um ArrayList de 1 milhão de comprimento. No meu 2.4Ghz MacBook, acessando o ArrayList através de uma interface List levou 2.10 segundos, em média, ao declarar que do tipo ArrayList que levou, em média, 1,67 segundos.

Se você estiver trabalhando com grandes listas, no fundo um loop interno ou frequentemente chamada de função, então isso é algo a considerar.

ArrayList e LinkedList são duas implementações de uma lista, que é uma coleção ordenada de itens. Logic-wise não importa se você usar um ArrayList ou LinkedList, então você não deve restringir o tipo de ser isso.

Isto contrasta com digamos, Recolha e Lista, que são coisas diferentes (Lista implica a classificação, coleção não).

Por que o último com Lista ser usado em vez de ArrayList?

É uma boa prática: Programa para fazer a interface ao invés de implementação

Ao substituir ArrayList com List, você pode alterar a implementação List no futuro como abaixo dependendo do seu caso de uso de negócios.

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).*/

ou

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.*/

ou

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

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

ou

alguma outra implementação List específico.

contrato define a interface List e implementação específica do List pode ser alterado. Desta forma, interface e implementação são de baixo acoplamento.

questão SE relacionadas:

O que significa a "programa para uma interface" ?

Mesmo para as variáveis ??locais, utilizando a interface sobre a classe concreta ajuda. Você pode acabar chamando um método que está fora da interface e, em seguida, é difícil mudar a implementação da lista, se necessário. Além disso, é melhor usar a classe menos específico ou interface em uma declaração. Se ordem dos elementos não importa, use uma coleção em vez de uma lista. Isso dá o seu código a máxima flexibilidade.

Propriedades de suas classes / interfaces devem ser expostos através de interfaces porque dá suas aulas um contrato de comportamento para uso, independentemente da implementação.

No entanto ...

Em declarações de variáveis ??locais, não faz muito sentido fazer isso:

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

Se a sua uma variável local, basta usar o tipo. Ainda é implicitamente upcastable à sua interface apropriada, e seus métodos devem espero que aceitam os tipos de interface para os seus argumentos, mas para as variáveis ??locais, faz total sentido para usar o tipo de implementação como um recipiente, apenas no caso de você precisar do implementação- funcionalidade específica.

Em geral, para a sua linha de código que não faz sentido se preocupar com interfaces. Mas, se estamos falando de APIs há uma razão muito boa. Eu tenho pequena classe

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

Neste caso é o uso da interface necessária. Porque eu quero contar o tamanho de todas as possíveis implementação incluindo o meu próprio costume. class MyList extends AbstractList<String>....

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top