1. Inizializzazione della doppia parentesi graffa
L'inizializzazione tramite doppie parentesi graffe (
di seguito denominata Inizializzazione delle doppie parentesi graffe ) è uno strumento Java per la creazione di raccolte come list, set e map contemporaneamente alla loro dichiarazione.
Quando sono necessari elenchi con elementi fissi, ad esempio un elenco di prodotti o valute supportati, la dichiarazione dell'elenco contemporaneamente alla sua inizializzazione migliora la leggibilità del codice. Questo è il motivo per cui l'inizializzazione con doppia parentesi graffa sta guadagnando popolarità, poiché non esistono altri metodi standard per creare raccolte con inizializzazione simultanea nel codice. Sfortunatamente, a differenza di altri linguaggi di programmazione, Java non supporta raccolte di valori letterali. A causa di questa limitazione, la creazione di una lista immodificabile
con anche un numero limitato di elementi ci costringe a scrivere molte righe di codice sotto forma di chiamate ripetute
add()
per aggiungere gli elementi desiderati con il ritorno a capo finale:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
Si tratta di una descrizione inutilmente ridondante che potrebbe essere semplificata. Compiliamo gli elenchi statici nel modo per noi conveniente, ovvero direttamente nei blocchi statici durante l'inizializzazione, che è ciò in cui
Double brace
l'inizializzazione ci aiuterà, permettendoci di scrivere tutto in una riga:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
add(2);
add(3);
add(5);
}});
Allo stesso modo,
Double brace
l'inizializzazione ci aiuterà a inserire valori e
HashMap
:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
put(1, "one");
put(2, "two");
put(3, "three");
}};
Sembra tutto così elegante, ma ha i suoi svantaggi, che rendono l'inizializzazione del Double brace un anti-pattern. Li esamineremo più approfonditamente nel prossimo capitolo.
Pro e contro dell'inizializzazione della doppia graffa.
Double
l'inizializzazione delle parentesi graffe utilizza la creazione di una classe
interna anonima . Ciò che inizialmente è nascosto in superficie, tuttavia,
Double brace
l'inizializzazione crea una classe con un'ulteriore inizializzazione della sua istanza ogni volta che la si utilizza. Inoltre viene utilizzato un riferimento nascosto a questa classe privata, che può portare a possibili perdite di memoria. Inoltre, non è possibile utilizzare l'operatore fantasma per i generici (operatore diamante < >), poiché non possiamo accedere all'interno di una classe anonima.
(Dal traduttore: Ancora una volta più in dettaglio:
dopo la prima { viene creata una classe anonima interna, dopo la seconda { l'inizializzazione avviene quando si crea un'istanza della classe, in cui abbiamo accesso ai campi e ai metodi della classe esterna ( relativo alla classe anonima).) |
Professionisti:
- Ridurre le righe nel codice
- Creazione e inizializzazione in un'unica espressione.
Aspetti negativi:
- Creare una classe anonima nascosta a te.
- Il che ci costa costi aggiuntivi per la sua istanza ogni volta che la utilizziamo.
- Ogni volta che viene creato un riferimento nascosto ad esso, il che può portare a perdite di memoria.
Verdetto: A causa degli svantaggi di cui sopra e dell'esistenza di alternative alla doppia graffa, l'inizializzazione è considerata un anti-pattern nel mondo Java.
Alternative all'inizializzazione della doppia graffa in Java
La buona notizia è che esistono altri modi per raggiungere gli stessi obiettivi in Java. Possiamo implementare in una riga di codice la creazione e l'inizializzazione di un ArrayList utilizzando il costruttore Copy della classe Collection come mostrato di seguito:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()
ci restituirà un elenco di lunghezza fissa passato al
ArrayList
costruttore della copia. Tieni presente la differenza tra gli elenchi a lunghezza fissa restituiti da
Arrays.asList()
e
Collections.unmodifiableList()
: non puoi aggiungere o rimuovere elementi
ArrayList
di - , ma puoi modificare un elemento per indice utilizzando
set()
, cosa che non puoi fare con un elenco restituito da
Collections.unmodifiableList()
. Se vuoi ottenere un piccolo elenco, questo è il modo migliore, anche se sarà meno trasparente per
Set
le altre raccolte, quindi dovrai crearlo
List
prima di creare
Set
-a. Ma questo è comunque meglio dell'inizializzazione con doppia parentesi graffa, poiché in questo caso non viene creata una classe anonima interna aggiuntiva ogni volta che viene utilizzata. Se stai utilizzando Java 8 hai un altro metodo alternativo. L'API JDK 8 Stream ti aiuterà a creare piccole raccolte combinando
Stream Factory
i metodi di output in una raccolta
List
:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
Perché
Set
puoi utilizzare
Collectors.toSet()
il metodo invece
Collectors.toList()
come di seguito:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
A proposito,
Stream collect
i metodi non garantiscono che le raccolte che generano siano protette dalle modifiche. In Java 8, le raccolte restituite (come -
ArrayList
,
HashSet
, e
HashMap
) sono abbastanza comuni (possiamo modificarle), ma questo fatto potrebbe essere corretto nelle future versioni di JDK. Per ora è tutto sull'inizializzazione
Double brace
in Java. Questo modello è accettabile per test e demo, ma non abbastanza buono per l'uso in produzione. A causa dei suoi svantaggi intrinseci, l'inizializzazione del doppio rinforzo è diventata oggigiorno un anti-modello, soprattutto considerando le alternative disponibili. Io stesso utilizzo ancora questa costruzione per inizializzare mappe statiche e basta. Perché
List
preferisco creare
Collections
combinando con la creazione
Array.asList
nel suo costruttore. E se utilizzo Java 8, un progetto che utilizza l'API Stream e
collect()
.
Articoli correlati: se ti è piaciuto questo tutorial e desideri saperne di più sui modelli, i principi e le migliori pratiche di programmazione Java, potresti voler consultare anche gli altri articoli sul nostro
sito .
Lettura consigliata: se vuoi saperne di più sui modelli e sulle migliori pratiche dovresti leggere
Programmazione efficace di Joshua Bloch , nessun libro può prendere il suo posto. E se sei già esperto in Java e stai cercando un libro sui design pattern, il cui stile di presentazione umoristico sia interessante e di facile lettura, presta attenzione a
“Head First. Modelli di progettazione" .
Dal traduttore: ho volutamente fornito un collegamento al libro originale di Bloch, poiché la sua traduzione in russo non ha avuto successo (ad esempio, Builder = costruttore). |
Traduzione dell'articolo Che cos'è l'inizializzazione di Double Brace in Java? Esempio di Anti Pattern (pubblicato nell'ottobre 2015).
GO TO FULL VERSION