Por que java.util.ArrayList permite adicionar nulo?

41

Gostaria de saber por que java.util.ArrayList permite adicionar null . Existe algum caso em que eu queira adicionar null a um ArrayList ?

Estou fazendo esta pergunta porque em um projeto tivemos um bug em que alguns códigos estavam adicionando null ao ArrayList e era difícil identificar onde estava o erro. Obviamente, um NullPointerException foi lançado, mas não até que outro código tentasse acessar o elemento. O problema era como localizar o código que adicionava o objeto null . Teria sido mais fácil se ArrayList tivesse lançado uma exceção no código onde os elementos estavam sendo adicionados.

    
por Alfredo Osorio 03.09.2012 / 16:30
fonte

7 respostas

38

Esta decisão de design aparece principalmente pela nomeação.

O nome ArrayList sugere ao leitor uma funcionalidade semelhante às matrizes - e é natural para O Java Collections Framework espera que a grande maioria dos utilizadores da API dependa do seu funcionamento semelhante aos arrays.

Isso, em particular, envolve o tratamento de elementos nulos. Usuário da API sabendo que abaixo funciona OK:

array[0] = null; // NPE won't happen here

seria bastante surpreso para descobrir se código semelhante para ArrayList jogaria NPE:

arrayList.set(0, null); // NPE => WTF?

O raciocínio como acima é apresentado em JCF tutorial enfatizando pontos que sugerem uma similaridade próxima entre ArrayList e matrizes simples:

ArrayList... offers constant-time positional access and is just plain fast...

Se você quiser uma implementação de Lista que não permita nulos, é melhor que ela seja chamada como NonNullableArrayList ou algo assim, para evitar confundir os usuários da API.

Nota lateral há uma discussão auxiliar nos comentários abaixo, junto com considerações adicionais apoiando o raciocínio apresentado aqui.

    
por 03.09.2012 / 17:01
fonte
30

Nulo pode ser um valor válido para um elemento de uma lista. Digamos que sua lista contenha elementos que representem alguns dados opcionais sobre uma lista de usuários e sejam armazenados na mesma ordem que os usuários. Se os dados extras forem preenchidos, sua lista conterá os dados adicionais, caso contrário, o slot correspondente a um usuário será nulo. (Tenho certeza de que há exemplos melhores, mas você entendeu)

se você não quiser permitir que os nulos sejam adicionados, poderá encapsular a lista de matrizes com seu próprio wrapper, que foi lançado quando o valor nulo foi adicionado.

    
por 03.09.2012 / 16:43
fonte
16

ArrayList permite null por design. É intencional. Do javadoc :

"[ArrayList is a] resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null."

A resposta para "por que" é que, se não fosse a ArrayList, não seria utilizável nos casos em que fosse necessário colocar um null na lista. Por outro lado, você pode impedir que um ArrayList contenha valores nulos testando os valores antes de adicioná-los ou usando um wrapper que evite que isso aconteça.

Is there any case where I would want to add null to an ArrayList?

Obviamente, qualquer caso em que null tenha um significado distinto. Por exemplo, pode significar que o valor em uma determinada posição na lista não foi inicializado ou fornecido.

It would have been easier if the ArrayList had thrown an exception in the code where the elements was being added.

Você pode implementar facilmente esse comportamento criando uma classe de wrapper. No entanto, esse não é o comportamento que os mais programadores / aplicativos precisam.

    
por 03.09.2012 / 16:50
fonte
8

Existe algum caso em que eu queira adicionar null a um ArrayList?

Claro, e quanto à pré-alocação? Você quer um ArrayList de itens que você não pode criar porque você não tem informações suficientes. Só porque você não pode pensar em uma razão pela qual alguém pode querer fazer alguma coisa, não é uma má idéia. Tanto faz. (Agora, tenho certeza que alguém virá e dirá que você deveria ter objetos vazios que preencham algum padrão que eles lêem em algum blog obscuro e que programadores deveriam realmente ser capazes de escrever programas sem nunca usar if declarações, blá blá .)

Se vocês têm um contrato que nunca deveria haver null s em um container, cabe a você garantir que o contrato seja cumprido, provavelmente de forma mais apropriada, afirmando. Isso provavelmente teria levado no máximo 10 linhas de código. Java torna incrivelmente fácil para você fazer esse tipo de coisa. O JDK não consegue ler sua mente.

    
por 03.09.2012 / 18:11
fonte
4

Esta parece ser mais uma questão filosófica (de software) aqui.

ArrayList como uma classe de utilitário foi projetada para ser útil em um contexto amplo de possíveis casos de uso.

Ao contrário da sua afirmação oculta de que aceitar null como um valor válido deve ser desencorajado, há muitos exemplos em que o valor nulo é perfeitamente legal.

O motivo mais importante é que null é o equivalente a do not know de qualquer tipo de referência, incluindo tipos de estrutura. Isto implica que null não pode ser substituído em qualquer caso por uma versão mais fluente do valor nothing .

Então, digamos que você armazene os inteiros 1, 3, 7 na sua arraylist no seu índice correspondente: Devido a alguma computação, você deseja obter o elemento no índice 5, então o seu array deve retornar é: "nenhum valor armazenado". Isto pode ser conseguido através do retorno de null ou um NullObject . Na maioria dos casos, retornar o valor nulo embutido é expressivo o suficiente. Depois de chamar um método que pode retornar null e usar seu valor de retorno, uma verificação do valor retornado em relação a null é bastante comum no código moderno.

    
por 16.07.2014 / 13:01
fonte
3

A declaração

File f = null;

é válido e útil (acho que não preciso explicar por quê). Também é útil ter uma coleção de arquivos, alguns dos quais podem ser nulos.

List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);

A utilidade de coleções que podem conter objetos nulos procede diretamente da utilidade de objetos que podem ser nulos. É realmente tão simples assim.

    
por 09.10.2014 / 02:08
fonte
2

É mais fácil aceitar tudo do que ser restritivo e tentar abrir o design depois do fato.

Por exemplo, e se o oracle / sun fornecesse apenas NonNullableArrayList, mas você queria poder adicionar um Null à sua lista. Como você faria? Você provavelmente teria que criar um objeto totalmente diferente, você não poderia usar estender o NonNullableArrayList. Em vez disso, se você tem um ArrayList que leva tudo, você poderia facilmente estendê-lo e substituir o add, onde ele não aceita valores nulos.

    
por 03.09.2012 / 17:45
fonte