En Hidden Features of Java, la respuesta principal menciona Double Brace Initialization , con una sintaxis muy atractiva:
Set<String> flavors = new HashSet<String>() {{
add("vanilla");
add("strawberry");
add("chocolate");
add("butter pecan");
}};
Este idioma crea una clase interna anónima con solo un inicializador de instancia, que "puede usar cualquier método [...] en el ámbito de contención".
Pregunta principal: ¿Es tan ineficiente como parece? ¿Debería limitarse su uso a inicializaciones únicas? (¡Y por supuesto presumiendo!)
Segunda pregunta: El nuevo HashSet debe ser el "this" utilizado en el inicializador de instancia ... ¿alguien puede arrojar luz sobre el mecanismo?
Tercera pregunta: ¿Es este idioma demasiado oscuro para usar en el código de producción?
Resumen: Muy, muy buenas respuestas, gracias a todos. En la pregunta (3), la gente sintió que la sintaxis debería ser clara (aunque recomendaría un comentario ocasional, especialmente si su código pasará a los desarrolladores que pueden no estar familiarizados con él).
En la pregunta (1), el código generado debería ejecutarse rápidamente. Los archivos .class adicionales causan desorden en los archivos jar y retrasan un poco el inicio del programa (gracias a @coobird por medir eso). @Thilo señaló que la recolección de basura puede verse afectada, y el costo de memoria para las clases cargadas adicionales puede ser un factor en algunos casos.
La pregunta (2) resultó ser la más interesante para mí. Si entiendo las respuestas, lo que sucede en DBI es que la clase interna anónima extiende la clase del objeto que está construyendo el nuevo operador y, por lo tanto, tiene un "este" valor que hace referencia a la instancia que se está construyendo. Muy aseado.
En general, DBI me parece una especie de curiosidad intelectual. Coobird y otros señalan que puede lograr el mismo efecto con Arrays.asList, métodos varargs, Google Collections y los literales propuestos para la Colección Java 7. Los nuevos lenguajes JVM como Scala, JRuby y Groovy también ofrecen anotaciones concisas para la construcción de listas, e interoperan bien con Java. Dado que DBI abarrota el classpath, ralentiza un poco la carga de la clase y hace que el código sea un poco más oscuro, probablemente lo evitaría. ¡Sin embargo, planeo lanzar esto a un amigo que acaba de obtener su SCJP y ama las justas bondadosas sobre la semántica de Java! ;-) ¡Gracias a todos!
7/2017: Baeldung tiene un buen resumen de la inicialización de doble paréntesis y lo considera un antipatrón.
12/2017: @Basil Bourque señala que en el nuevo Java 9 puedes decir:
Set<String> flavors = Set.of("vanilla", "strawberry", "chocolate", "butter pecan");
Ese es seguro el camino a seguir. Si está atascado con una versión anterior, eche un vistazo a ImmutableSet de Google Collections .
Set<String> flavors = Set.of( "vanilla" , "strawberry" , "chocolate" , "butter pecan" ) ;
flavors
ser unHashSet
, pero lamentablemente es una subclase anónima.