¿Por qué este código de Java está entre llaves ({}) fuera de un método?

Me estoy preparando para un examen de certificación de Java y he visto el código ME GUSTA en una de las pruebas de práctica:

class Foo { int x = 1; public static void main(String [] args) { int x = 2; Foo f = new Foo(); f.whatever(); } { x += x; } // <-- what's up with this? void whatever() { ++x; System.out.println(x); } } 

Mi pregunta es … ¿Es válido escribir código con llaves al margen de un método? ¿Cuáles son los efectos de estos (si los hay)?

Prestado de aquí –

Normalmente, pondrías código para inicializar una variable de instancia en un constructor. Hay dos alternativas al uso de un constructor para inicializar variables de instancia: bloques de inicialización y métodos finales. 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 comstackdor 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.

También puede mirar las discusiones aquí .

Se trata de un bloque de inicialización que se ejecuta mientras se carga / crea la instancia de la clase y que se utiliza para inicializar las propiedades de miembro de una clase (consulte Java http://download.oracle.com/javase/tutorial/java/javaOO). /initial.html ). Puede tener tantos bloques como desee y se crearán instancias de arriba a abajo.

Además del bloque de instancia, también puede tener tantos bloques estáticos como desee para inicializar miembros estáticos. Serían declarados de la siguiente manera:

 public class Initialization { static int b = 10; int a = 5; static { b = -9; } { a += 2; } public static void main(String[] args) throws Exception { System.out.println(ClientVoting.b); System.out.println(new ClientVoting().a); System.out.println(ClientVoting.b); System.out.println(new ClientVoting().a); } static { b = 1; } { a++; } } 

Mientras se inicializa la clase, el miembro estático “b” se inicializa como 10, luego el primer ámbito estático cambia su valor a -9, y luego a 1. Esto solo se ejecuta una vez mientras se carga la clase. Esto se ejecuta antes de la inicialización de la primera línea del método principal.

Por otro lado, el ejemplo similar para su clase es la referencia de instancia “a”. A se inicializa como 5, luego el bloque de instancia lo actualiza a 7 y el último a 8. Como se esperaba, los miembros estáticos solo se inicializan una vez en este código, mientras que los bloques de instancia se ejecutan CADA vez que se crea una nueva instancia.

El resultado de este ejemplo es 1 8 1 8

Es un bloque inicializador . Se usa para establecer variables de instancia. La motivación para usar bloques de inicialización sobre constructores es evitar escribir código redundante. El comstackdor de Java copia el contenido del bloque en cada constructor.