Java blocks have multiple applications
Body of classes and methods
Class:
class C { ... }
Method:
void m() { ... }
Implementations inline:
Runnable r = new Runnable() {
public void run() { ... }
};
Group statements into conditional, ties and exceptional control
Conditional:
if (cond) { ... } else { ... }
switch (valor) { case 1: ...; break; default: ...}
Ties:
while (cond) { ... }
do { ... } while (cond)
for (...) { ... }
Exceptional control and closure:
try { ... } catch { ... } finally { ... }
Arbitrary blocks
They are placed in the middle of the code and follow the normal flow of execution, but with their own scope, which means that the declared variables will no longer exist at their closure.
int a = 1;
{
int b = a + 2; //b == 3
}
//b não existe mais
This is probably allowed by a language question, that is, a block can replace a valid command in Java grammar. This greatly simplifies implementation because the compiler does not need to do a special check to allow blocks only in specific commands.
Labels
It is possible to use the command break <label>
to interrupt the execution of a specific block.
I couldn’t think of any practical application, so go an example without the slightest sense anyway:
int a = 1;
myLabel: {
for (int i = 0; i < 20; i++) {
a++;
if (a == 5) {
break myLabel;
}
}
System.out.println("Não vai imprimir isso!");
}
System.out.println(a);
Instance and class initializers
Instance (runs before constructor):
classe C {
{ ... }
}
Static (executes when class is loaded on first use:
classe C {
static { ... }
}
The order of execution
An interesting question about the boot blocks is about the order in which they are executed, whereas there is the object constructor and attribute initializations.
Consider the following example:
public class Initializations {
static class X {
static int y(String str) {
System.out.println("y(" + str + ")");
return 1;
}
}
static class A {
static {
System.out.println("static initializer A");
}
static int y = X.y("static A");
int y2 = X.y("instance A");
{
System.out.println("instance initializer A");
}
public A() {
System.out.println("constructor A");
}
}
static class B extends A {
static int y = X.y("static B");
int y2 = X.y("instance B");
static {
System.out.println("static initializer B");
}
{
System.out.println("instance initializer B");
}
public B() {
System.out.println("constructor B");
}
public void imprime() {
System.out.println("imprime()");
}
}
public static void main(String[] args) {
System.out.println("init main");
new B().imprime();
System.out.println("end main");
}
}
I will comment on the result produced by the above code:
init main
: the first item is from the method main
, soon the subclasses were not initialized.
static initializer A
: when executing new B()
Java first executes the static initializer of the Parent class.
y(static A)
: then the static attribute y
class A
was initialized.
y(static B)
: then the static attribute y
class B
was initialized.
static initializer B
: now, yes the static initializer of B
.
y(instance A)
: now the instance attribute y2
class A
.
instance initializer A
: now the class instance initializer A
.
constructor A
: and the builder of A
.
y(instance B)
: now the instance attribute y2
class B
.
instance initializer B
: and the instance initializer of B
.
constructor B
: ending the boot sequence, Java runs the constructor of B
.
imprime()
: and the instance method is called.
end main
: finally the method main
ends.
Based on this, we can say that the execution order is:
- Static variables and initializers, starting from the parent class and ending from the daughter, and the order in which they are declared in the body of each hierarchy class.
- Starting again in the parent class and ending in the daughter, initialization of instance variables, instance initializers and constructors are executed in this order.
It would be if it were a class without
main
. Then it would be exactly oneInstance Initializer
.– Felipe Avelar
@Felipeavelar is still a
Instance Initializer
the fact that you have amain
it does not matter, what happens is that as there is created a de facto instance of this class, aInstance Initializer
is not called, if it were aStatic Initializer
would be.– pepper_chico