1. Inicialização de colchetes duplos
A inicialização usando colchetes duplos (
doravante denominada inicialização de colchetes duplos ) é uma ferramenta Java para criar coleções como lista, conjunto e mapa simultaneamente com sua declaração.
Quando você precisar de listas com elementos fixos, como uma lista de produtos suportados ou unidades monetárias, declarar a lista ao mesmo tempo que a inicializa melhora a legibilidade do código. É por isso que a inicialização com colchetes duplos está ganhando popularidade, uma vez que não existem outros métodos padrão para criar coleções com inicialização simultânea no código. Infelizmente, diferentemente de outras linguagens de programação, Java não oferece suporte a coleções de literais. Devido a essa limitação, criar uma lista não modificável mesmo
com um pequeno número de elementos nos força a escrever muitas linhas de código na forma de chamadas repetidas
add()
para adicionar os elementos desejados com empacotamento final:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Esta é uma descrição desnecessariamente redundante que poderia ser simplificada. Vamos preencher as listas estáticas de uma forma que nos seja conveniente, nomeadamente diretamente em blocos estáticos durante a inicialização, que é nisso que
Double brace
a inicialização nos ajudará, permitindo-nos escrever tudo numa linha:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
add(2);
add(3);
add(5);
}});
Da mesma forma,
Double brace
a inicialização nos ajudará a preencher valores e
HashMap
:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
put(1, "one");
put(2, "two");
put(3, "three");
}};
Tudo parece tão elegante, mas tem suas desvantagens, que tornam a inicialização com colchetes duplos um antipadrão. Iremos examiná-los mais detalhadamente no próximo capítulo.
Prós e contras da inicialização com colchetes duplos.
Double
A inicialização de chaves usa a criação de uma classe
interna anônima . O que está inicialmente oculto na superfície, entretanto,
Double brace
a inicialização cria uma classe com inicialização adicional de sua instância toda vez que você a usa. Além disso, é utilizada uma referência oculta a esta classe privada, o que pode nos levar a possíveis vazamentos de memória. Você também não pode usar o operador fantasma para genéricos (operador diamante < >), pois não podemos acessar o interior de uma classe anônima.
(Do tradutor: Mais uma vez com mais detalhes:
após o primeiro { é criada uma classe anônima interna, após o segundo { ocorre a inicialização ao criar uma instância da classe, durante a qual temos acesso aos campos e métodos do externo ( em relação à classe anônima).) |
Prós:
- Reduzindo linhas no código
- Criação e inicialização em uma expressão.
Desvantagens:
- Criando uma classe anônima escondida de você.
- O que nos custa custos adicionais por sua instância cada vez que a usamos.
- Cada vez que uma referência oculta é criada, o que pode levar a vazamentos de memória.
Veredicto: Devido aos contras acima e à existência de alternativas ao colchete duplo, a inicialização é vista como um antipadrão no mundo Java.
Alternativas para inicialização de colchetes duplos em Java
A boa notícia é que existem outras maneiras de atingir os mesmos objetivos em Java. Podemos implementar em uma linha de código a criação e inicialização de um ArrayList usando o construtor Copy da classe Collection conforme mostrado abaixo:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()
nos retornará uma lista de comprimento fixo passada para
ArrayList
o construtor de cópia. Tenha em mente a diferença entre listas de comprimento fixo retornadas por
Arrays.asList()
e
Collections.unmodifiableList()
: você não pode adicionar ou remover elementos
ArrayList
de - , mas pode alterar um elemento pelo índice usando
set()
, o que não pode ser feito com uma lista retornada por
Collections.unmodifiableList()
. Se você deseja obter uma lista pequena, esta é a melhor maneira, embora seja menos transparente para
Set
outras coleções, então você terá que criá-la
List
antes de criar
Set
-a. Mas isso ainda é melhor do que a inicialização com colchetes duplos, pois neste caso uma classe anônima interna extra não é criada toda vez que ela é usada. Se você estiver executando o Java 8, terá outro método alternativo. A API JDK 8 Stream ajudará você a criar pequenas coleções combinando
Stream Factory
métodos de saída em uma coleção
List
:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
Pois
Set
você pode usar
Collectors.toSet()
o método
Collectors.toList()
abaixo:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
A propósito,
Stream collect
os métodos não garantem que as coleções que geram estejam protegidas contra alterações. No Java 8, as coleções retornadas (como -
ArrayList
,
HashSet
, e
HashMap
) são bastante comuns (podemos alterá-las), mas esse fato pode ser corrigido em versões futuras do JDK. Por enquanto é tudo sobre
Double brace
inicialização em Java. Este modelo é aceitável para testes e demonstrações, mas não é bom o suficiente para uso em produção. Devido às suas desvantagens inerentes, a inicialização com colchetes duplos tornou-se um antipadrão atualmente, especialmente dadas as alternativas disponíveis. Eu mesmo ainda uso essa construção para inicializar mapas estáticos e pronto. Pois
List
prefiro criar
Collections
combinando com a criação
Array.asList
em seu construtor. E se eu usar Java 8 - um design usando a API Stream e
collect()
.
Artigos relacionados: Se você gostou deste tutorial e deseja aprender mais sobre padrões, princípios e práticas recomendadas de programação Java, você também pode verificar os outros artigos em nosso
site .
Leitura recomendada: Se você quiser aprender mais sobre padrões e melhores práticas, leia
Effective Programming, de Joshua Bloch , nenhum livro pode substituí-lo. E se você já é proficiente em Java e está procurando um livro sobre padrões de design, cujo estilo humorístico de apresentação seja interessante e fácil de ler, preste atenção em
“Head First. Padrões de design" .
Do tradutor: forneci deliberadamente um link para o livro original de Bloch, uma vez que sua tradução para o russo não foi bem-sucedida (por exemplo, Builder = construtor). |
Tradução do artigo O que é inicialização com colchetes duplos em Java? Exemplo de antipadrão (publicado em outubro de 2015).
GO TO FULL VERSION