Qu'est-ce que la syntaxe d'initialisation Double Brace ( {{ ... }}
) en Java?
java
initialization
double-brace-initialize
sgokhales
la source
la source
Réponses:
L'initialisation à double accolade crée une classe anonyme dérivée de la classe spécifiée (les accolades externes ) et fournit un bloc d'initialisation au sein de cette classe (les accolades internes ). par exemple
Notez qu'un effet de l'utilisation de cette initialisation à double accolade est que vous créez des classes internes anonymes. La classe créée a un
this
pointeur implicite vers la classe externe environnante. Bien que ce ne soit normalement pas un problème, il peut provoquer des problèmes dans certaines circonstances, par exemple lors de la sérialisation ou de la collecte des ordures, et cela vaut la peine d'être conscient de cela.la source
Chaque fois que quelqu'un utilise l'initialisation à double accolade, un chaton est tué.
Outre que la syntaxe est plutôt inhabituelle et pas vraiment idiomatique (le goût est discutable, bien sûr), vous créez inutilement deux problèmes importants dans votre application, dont je viens récemment de bloguer plus en détail ici .
1. Vous créez beaucoup trop de classes anonymes
Chaque fois que vous utilisez l'initialisation à double accolade, une nouvelle classe est créée. Par exemple, cet exemple:
... produira ces classes:
C'est un peu de surcharge pour votre chargeur de classe - pour rien! Bien sûr, cela ne prendra pas beaucoup de temps d'initialisation si vous le faites une fois. Mais si vous faites cela 20'000 fois dans votre application d'entreprise ... tout ce tas de mémoire juste pour un peu de "sucre de syntaxe"?
2. Vous créez potentiellement une fuite de mémoire!
Si vous prenez le code ci-dessus et renvoyez cette carte à partir d'une méthode, les appelants de cette méthode peuvent s'accrocher sans trop de ressources à des ressources très lourdes qui ne peuvent pas être récupérées. Prenons l'exemple suivant:
Le retour
Map
contiendra désormais une référence à l'instance englobante deReallyHeavyObject
. Vous ne voulez probablement pas risquer que:Image de http://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/
3. Vous pouvez prétendre que Java a des littéraux de carte
Pour répondre à votre question réelle, les gens ont utilisé cette syntaxe pour prétendre que Java a quelque chose comme des littéraux de carte, similaires aux littéraux de tableau existants:
Certaines personnes peuvent trouver cela stimulant sur le plan syntaxique.
la source
{{...}}
et déclaré en tant questatic
champ, il ne devrait pas y avoir de fuite de mémoire possible, une seule classe anonyme et aucune référence d'instance incluse, non?Map.of()
à cet effet, donc ce sera une meilleure solutionReallyHeavyObject
. De plus, les classes internes anonymes capturent toutes les variables locales utilisées dans le corps de la classe, donc si vous utilisez non seulement des constantes pour initialiser des collections ou des mappes avec ce modèle, les instances de classe interne les captureront toutes et continueront de les référencer même lorsqu'elles seront réellement supprimées de la collection ou la carte. Donc, dans ce cas, ces instances n'ont pas seulement besoin de deux fois plus de mémoire que nécessaire pour les références, mais ont une autre fuite de mémoire à cet égard.Par exemple:
Comment ça fonctionne
La première accolade crée une nouvelle classe intérieure anonyme. Ces classes internes sont capables d'accéder au comportement de leur classe parent. Donc, dans notre cas, nous créons en fait une sous-classe de la classe HashSet, donc cette classe interne est capable d'utiliser la méthode put ().
Et le deuxième ensemble d'accolades n'est rien d'autre que des initialiseurs d'instance. Si vous rappelez les concepts de base de Java, vous pouvez facilement associer des blocs d'initialisation d'instance à des initialiseurs statiques en raison d'accolades similaires comme struct. La seule différence est que l'initialiseur statique est ajouté avec un mot clé statique et n'est exécuté qu'une seule fois; peu importe le nombre d'objets que vous créez.
plus
la source
Pour une application amusante d'initialisation à double accolade, voir ici Dwemthy's Array en Java .
Un extrait
Et maintenant, préparez-vous pour le bacon
BattleOfGrottoOfSausageSmells
et… gros morceaux!la source
Je pense qu'il est important de souligner qu'il n'y a rien de tel que «l'initialisation à double accolade» en Java . Le site Web d'Oracle n'a pas ce terme. Dans cet exemple, deux fonctionnalités sont utilisées ensemble: classe anonyme et bloc d'initialisation. Il semble que l'ancien bloc d'initialisation a été oublié par les développeurs et provoque une certaine confusion dans cette rubrique. Citation des documents Oracle :
Les blocs d'initialisation pour les variables d'instance ressemblent à des blocs d'initialisation statiques, mais sans le mot clé static:
la source
1- Il n'y a pas de double accolade:
je voudrais souligner qu'il n'y a pas de telle chose que l'initialisation de double accolade. Il n'y a qu'un bloc d'initialisation traditionnel à une seule accolade. Le deuxième bloc d'accolades n'a rien à voir avec l'initialisation. Les réponses disent que ces deux accolades initialisent quelque chose, mais ce n'est pas comme ça.
2- Il ne s'agit pas seulement de classes anonymes mais de toutes les classes:
Presque toutes les réponses disent que c'est une chose utilisée lors de la création de classes internes anonymes. Je pense que les gens qui liront ces réponses auront l'impression que cela n'est utilisé que lors de la création de classes internes anonymes. Mais il est utilisé dans toutes les classes. La lecture de ces réponses ressemble à une toute nouvelle fonctionnalité spéciale dédiée aux classes anonymes et je pense que cela est trompeur.
3- Le but est simplement de placer les supports les uns après les autres, pas un nouveau concept: pour
aller plus loin, cette question parle de la situation où le deuxième support d'ouverture se trouve juste après la première ouverture du support. Lorsqu'il est utilisé dans une classe normale, il y a généralement du code entre deux accolades, mais c'est totalement la même chose. Il s'agit donc de placer des crochets. Je pense donc que nous ne devons pas dire que c'est quelque chose de nouveau passionnant, parce que c'est la chose que nous savons tous, mais juste écrite avec du code entre crochets. Nous ne devons pas créer de nouveau concept appelé "initialisation à double accolade".
4- La création de classes anonymes imbriquées n'a rien à voir avec deux accolades:
je ne suis pas d'accord avec l'argument selon lequel vous créez trop de classes anonymes. Vous ne les créez pas à cause d'un bloc d'initialisation, mais simplement parce que vous les créez. Ils seraient créés même si vous n'utilisiez pas l'initialisation à deux accolades, de sorte que ces problèmes se produiraient même sans initialisation ... L'initialisation n'est pas le facteur qui crée des objets initialisés.
la source
Pour éviter tous les effets négatifs de l'initialisation à double accolade, tels que:
faire les choses suivantes:
Exemple:
Usage:
Avantages:
Désavantages:
Et, par conséquent, nous avons le modèle de générateur de java le plus simple jamais créé.
Voir tous les exemples sur github: java-sf-builder-simple-example
la source
C'est - entre autres utilisations - un raccourci pour initialiser des collections. Apprendre encore plus ...
la source
Tu veux dire quelque chose comme ca?
c'est une initialisation de liste de tableaux au moment de la création (hack)
la source
Vous pouvez mettre certaines instructions Java en boucle pour initialiser la collection:
Mais ce cas affecte les performances, consultez cette discussion
la source
Comme l'a souligné @Lukas Eder, l' initialisation des doubles accolades doit être évitée.
Il crée une classe interne anonyme, et puisque toutes les classes internes gardent une référence à l'instance parent, il peut - et 99% le sera probablement - empêcher la récupération de place si ces objets de collection sont référencés par plus d'objets que le seul déclarant.
Java 9 a introduit des méthodes pratiques
List.of
,Set.of
etMap.of
, qui doivent être utilisés à la place. Ils sont plus rapides et plus efficaces que l'initialiseur à double croisillon.la source
La première accolade crée une nouvelle classe anonyme et le deuxième ensemble d'accolades crée des initialiseurs d'instance comme le bloc statique.
Comme d'autres l'ont souligné, son utilisation n'est pas sûre.
Cependant, vous pouvez toujours utiliser cette alternative pour initialiser des collections.
la source
Il semblerait que ce soit le même que le mot clé with si populaire en flash et vbscript. C'est une méthode pour changer ce qui
this
est et rien de plus.la source
this
est. La syntaxe crée simplement une classe anonyme (donc toute référence àthis
ferait référence à l'objet de cette nouvelle classe anonyme), puis utilise un bloc d'initialisation{...}
afin d'initialiser l'instance nouvellement créée.