Java blokovi za inicijalizaciju koda: upoznavanje sa procesom inicijalizacije instance i statičke inicijalizacije
„Brate, danas učimo o ‘blokovima za inicijalizaciju koda’, zar ne?" Izgleda da je Sanmej već unapred pripremila domaći zadatak koji sam joj prošli put zadao.
„Da, Sanmej. Blokovi za inicijalizaciju koda služe za inicijalizaciju nekih članskih promenljivih." Odgovorio sam joj sa svojim običnim, iskrenim osmehom. „Prilikom kreiranja objekta izvršava se blok za inicijalizaciju koda, poznat i kao blok za inicijalizaciju instance — to ime služi prvenstveno da ga se razlikuje od statičkog bloka za inicijalizaciju."
„Može se direktno koristiti operator = za inicijalizaciju članskih promenljivih, ali blokom za inicijalizaciju koda može se uraditi i više — na primer ispisati vrednost članske promenljive nakon inicijalizacije."
„Sanmej, pogledaj sledeći kod — možemo direktno preko operatora = da inicijalizujemo člansku promenljivu."
class Bike{
int speed=100;
}„Brate, a zašto nam onda uopšte trebaju blokovi za inicijalizaciju koda?" Sanmej je trepnula i zbunjeno pitala.
„Pomoću bloka za inicijalizaciju koda možemo izvršiti složeniju operaciju, na primer popuniti vrednosti u kolekciju. Pogledaj sledeći kod."
public class Bike {
List<String> list;
{
list = new ArrayList<>();
list.add("Chenmo Wang Er");
list.add("Chenmo Wang San");
}
public static void main(String[] args) {
System.out.println(new Bike().list);
}
}„Kada bismo koristili samo operator =, ne bismo mogli da završimo inicijalizaciju kolekcije, zar ne? Iza = možemo samo da instanciramo kolekciju sa new, ali ne možemo da popunimo vrednosti — a blok za inicijalizaciju koda upravo to i radi."
„Konstruktor se izvršava pre ili blok za inicijalizaciju koda, brate?" To pitanje Sanmej je postavila prilično stručno.
„Ne žuri, Sanmej, prvo pogledaj sledeći primer."
public class Car {
Car() {
System.out.println("Konstruktor");
}
{
System.out.println("Blok za inicijalizaciju koda");
}
public static void main(String[] args) {
new Car();
}
}„Pogledajmo izlaz programa i odmah će nam biti jasno."
Blok za inicijalizaciju koda
Konstruktor„Gledano po rezultatu izlaza, izgleda kao da se blok za inicijalizaciju koda izvršava ranije, zar ne? Ali da li je zaista tako?" upitah Sanmej sa misterioznim osmehom.
„Zar ja vidim priviđenje?" Sanmej je raširila oči.
„Ne, objekat prilikom inicijalizacije prvo poziva konstruktor — to je van svake sumnje. Samo što konstruktor prilikom izvršenja stavlja blok za inicijalizaciju koda ispred ostalog koda u konstruktoru, pa zato prvo vidimo ‘Blok za inicijalizaciju koda’, a tek onda ‘Konstruktor’."
Kada sam to izgovorio, otvorio sam draw.io, potrošio sve snage i nacrtao sledeću sliku.

„Aha, tako dakle!" Sanmej je kao da je otkrila novi svet i značajno rekla: „Kompajler je stavio blok za inicijalizaciju koda u konstruktor — zato."
Kada je Sanmej to potpuno razumela, nastavio sam: „Za inicijalizaciju koda važe tri pravila."
- Blok za inicijalizaciju koda izvršava se kada se klasa instancira;
- U stvari, blok za inicijalizaciju koda se izvršava unutar konstruktora, samo što je smešten bliže početku;
- Naredbe u bloku za inicijalizaciju koda izvršavaju se redom, odozgo nadole.
„Ova pravila ne treba učiti napamet, dovoljno je da ih okvirno razumeš. Da pogledamo sledeći kod." Jedva što sam to izgovorio, već sam u novoj verziji IDE-e počeo brzo da kucam — nova verzija je zaista prava stvar.
class A {
A () {
System.out.println("Konstruktor roditeljske klase");
}
}
public class B extends A{
B() {
System.out.println("Konstruktor izvedene klase");
}
{
System.out.println("Blok za inicijalizaciju koda");
}
public static void main(String[] args) {
new B();
}
}„Pogledaj izlaz."
Konstruktor roditeljske klase
Blok za inicijalizaciju koda
Konstruktor izvedene klase„Podrazumevano, konstruktor izvedene klase prilikom izvršenja aktivno poziva konstruktor roditeljske klase. Drugim rečima, konstruktor se zaista izvršava prvi, a nakon njega blok za inicijalizaciju koda."
„Ovaj primer još jednom potvrđuje prethodno drugo pravilo: blok za inicijalizaciju koda izvršava se unutar konstruktora, samo što je smešten bliže početku."
Pored ovog bloka za inicijalizaciju instance, postoji i statička inicijalizacija, ali ćemo nju obraditi u okviru ključne reči static; ovde samo dajemo kratak pregled.
U nastavku je primer Java koda koji demonstrira upotrebu bloka za inicijalizaciju instance i statičkog bloka za inicijalizaciju:
public class Example {
// statička promenljiva
public static int staticVar = 1;
// promenljiva instance
public int instanceVar = 2;
// statički blok za inicijalizaciju
static {
System.out.println("Izvršava se statički blok za inicijalizaciju");
staticVar = 3;
}
// blok za inicijalizaciju instance
{
System.out.println("Izvršava se blok za inicijalizaciju instance");
instanceVar = 4;
}
// konstruktor
public Example() {
System.out.println("Izvršava se konstruktor");
}
public static void main(String[] args) {
System.out.println("Izvršava se main metoda");
Example e1 = new Example();
Example e2 = new Example();
System.out.println("Statička promenljiva objekta e1: " + e1.staticVar);
System.out.println("Promenljiva instance objekta e1: " + e1.instanceVar);
System.out.println("Statička promenljiva objekta e2: " + e2.staticVar);
System.out.println("Promenljiva instance objekta e2: " + e2.instanceVar);
}
}U ovom primeru koda postoji jedna statička promenljiva staticVar i jedna promenljiva instance instanceVar, kao i jedan statički blok za inicijalizaciju i jedan blok za inicijalizaciju instance. U statičkom bloku ispisali smo poruku i izmenili vrednost statičke promenljive; u bloku za inicijalizaciju instance takođe smo ispisali poruku i izmenili vrednost promenljive instance.
Pogledajmo rezultat izvršenja:
Izvršava se statički blok za inicijalizaciju
Izvršava se main metoda
Izvršava se blok za inicijalizaciju instance
Izvršava se konstruktor
Izvršava se blok za inicijalizaciju instance
Izvršava se konstruktor
Statička promenljiva objekta e1: 3
Promenljiva instance objekta e1: 4
Statička promenljiva objekta e2: 3
Promenljiva instance objekta e2: 4Iz rezultata izlaza se vidi da se statički blok za inicijalizaciju izvršava pri učitavanju klase, i to samo jednom, i to pre izvršenja bloka za inicijalizaciju instance i konstruktora; blok za inicijalizaciju instance izvršava se pri svakom kreiranju objekta, i to pre konstruktora.
„Dobro, za danas toliko. Odmaraj se u podne, posle podne ćeš imati više snage." Jedva što sam to rekao Sanmej, mahnula mi je javlje — uhvatila me je zehter.
