java - tag - Significado de la nueva clase(...){{...}} idioma de inicialización
current/most recent employer (4)
Esta pregunta ya tiene una respuesta aquí:
- ¿Qué es la inicialización de Double Brace en Java? 11 respuestas
¿Qué significa {{ ... }}
bloquear en el siguiente código?
class X {
private Y var1;
private X() {
Z context = new Z(new SystemThreadPool()) {{
var1 = new Y();
}};
}
}
Como se mencionó en las respuestas anteriores, la inicialización con doble llave es correcta.
Utiliza una técnica específica para Inicializar Miembros de Instancia en Java. Es una forma abreviada de definir en una definición de clase, un bloque compartido de código que se ejecutará cuando se active cualquiera de los constructores de clase.
Estoy agregando el enlace a la documentación oficial de Java que lo describe para una visión más amplia sobre el tema.
De la documentación :
Los bloques de inicializador para las variables de instancia se parecen a los bloques de inicializador estáticos, pero sin la palabra clave estática:
{
// whatever code is needed for initialization goes here
}
El compilador de Java copia bloques de inicializador en cada constructor. Por lo tanto, este enfoque se puede usar para compartir un bloque de código entre múltiples constructores.
Estás creando una clase anónima y utilizando la clase Instance initialize r idiom, así:
class X {
private Y var1;
private X() {
Z context = new Z(
new SystemThreadPool()) {
{ // This is the initialize idiom
var1 = new Y(); //
} //
}
); // BTW you are missing ")"
}
}
Las llaves "externas" significan que estás haciendo una subclase anónima, las segundas llaves son el inicializador de objetos. El inicializador se ejecuta antes del constructor de la clase, pero después de cualquier super
llamada (y por lo tanto también después de cualquier inicializador de superclase). También puede utilizar inicializadores en clases no anónimas, que es una forma conveniente de iniciar campos final
si tiene varios constructores que no se pueden llamar entre sí, o campos que necesitan una inicialización más compleja de lo que permiten los inicializadores de campo habituales.
Considera esta clase:
class X extends Y{
private final int lulz;
private static boolean someCondition(){...}
private static boolean danger() throws SomeException { ... }
public X(A a) throws SomeException {
super(a);
lulz = someCondition()? danger() : 0;
}
public X(B b) throws SomeException {
super(b);
lulz = someCondition()? danger() : 0;
}
}
Podría ser reescrito como:
class X extends Y{
private final int lulz;
private static boolean someCondition(){...}
private static boolean danger() throws SomeException { ... }
{ // initalizer -- might throw SomeException!
lulz = someCondition()? danger() : 0;
}
public X(A a) throws SomeException { super(a); }
public X(B b) throws SomeException { super(b); }
}
Si el inicializador puede arrojar una excepción marcada, todos los constructores deben declarar que pueden lanzarla.
Se llama inicialización con doble llave . (EDITAR: Enlace eliminado, archivado aquí )
Significa que estás creando una subclase anónima y el código dentro de las llaves dobles es básicamente un constructor. A menudo se usa para agregar contenidos a las colecciones porque la sintaxis de Java para crear lo que esencialmente son constantes de colección es algo incómodo.
Entonces puedes hacer:
List<String> list = new ArrayList<String>() {{
add("one");
add("two");
add("three");
}};
en lugar de:
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
En realidad, no me gusta eso y prefiero hacer esto:
List<String> list = Arrays.asList("one", "two", "three");
Por lo tanto, no tiene mucho sentido en ese caso mientras que lo hace para, por ejemplo, Maps, que no tienen un ayudante conveniente.