Czerwiec 12, 2019

Static Initialization – statyczny inicjalizator w Javie

Czym jest Static Initialization?

Static Initialization lub statyczny inicjalizator w Javie jest blokiem kodu rozpoczynającym się od słowa kluczowego static, który jest wywoływany po załadowaniu danej klasy.

Owy blok kodu wywoła się dokładnie tylko jeden raz – w przypadku, gdy użyjemy danej klasy. Jego użycie jest bardzo proste, wystarczy stworzyć klamry ze słowem kluczowym static w dowolnej klasie:

public class StaticExample {
    static {
        System.out.println("Java static initialization");
    }
}

Static initialization jest używany do inicjazali pól statycznych w klasie – np. do uzupełnienia mapy odpowiednimi wartościami.

import com.sun.org.apache.regexp.internal.RE;

import java.util.HashMap;
import java.util.Map;

public enum Field {
    REPORTER("reporter"),
    ASSIGNEE("assignee");

    public static final Map<Field, FieldService> fieldServicesMap = new HashMap<>();

    static {
        System.out.println("Static initializing...");
        fieldServicesMap.put(REPORTER, new ReporterService());
        fieldServicesMap.put(ASSIGNEE, new AssigneeService());
        System.out.println("End of static initializing");
    }

    private final String name;

    Field(String name) {
        this.name = name;
    }
}

Gdybyśmy nie mieli możliwości używania bloku statycznej inicjalizacji moglibyśmy podobne zachowanie wymuścić wywołaniem statycznej metody:

import com.sun.org.apache.regexp.internal.RE;

import java.util.HashMap;
import java.util.Map;

public enum Field {
    REPORTER("reporter"),
    ASSIGNEE("assignee");

    public static final Map<Field, FieldService> fieldServicesMap = initFieldServiceMap();


    private static Map<Field, FieldService> initFieldServiceMap() {
        Map<Field, FieldService> map = new HashMap<>();
        System.out.println("Static initializing...");
        map.put(REPORTER, new ReporterService());
        map.put(ASSIGNEE, new AssigneeService());
        System.out.println("End of static initializing");
        return map;
    }

    private final String name;

    Field(String name) {
        this.name = name;
    }
}

Aby sprawdzić czy, aby na pewno statyczna inicjalizacja wywołuje się jeszcze przed użyciem klasy wystarczy uruchomić taki przykład:

public class Main {
    public static void main(String[] args) {
        System.out.println("Main method");
        System.out.println(Field.ASSIGNEE);
    }
}

Jak widać dopiero w momencie użycia typu Field statyczny inicjalizator się wywołuje:

Main method
Static initializing...
End of static initializing
ASSIGNEE

Kod całego przykładu znajdziesz w tym repozytorium.