Inicjalizacja statyczna w Javie

Moje pytanie dotyczy jednego użycia słowa kluczowego statycznego. Możliwe jest użycie słowa kluczowego static do pokrycia bloku kodu w klasie, który nie należy do żadnej funkcji. Na przykład następujące Kompilacje kodu:

public class Test {
    private static final int a;    
    static {
        a = 5;
        doSomething(a);
    }
    private static int doSomething(int x) {
        return (x+5);
    }
}

Jeśli usuniesz słowo kluczowe static, narzeka, ponieważ zmienna a to final. Możliwe jest jednak usunięcie zarówno słów kluczowych final, jak i static i zmuszenie ich do kompilacji.

To jest dla mnie mylące w obu aspektach. Jak mam mieć sekcję kodu, która nie należy do żadnej metody? Jak można się do niego powołać? Ogólnie rzecz biorąc, jaki jest cel tego użycia? Albo lepiej, gdzie mogę znaleźć dokumentację na ten temat?
Author: Carlos Heuberger, 2008-12-02

9 answers

Blok kodu z modyfikatorem statycznym oznacza inicjalizator klasy ; bez modyfikatora statycznego blok kodu jest inicjalizatorem instancji .

Inicjalizatory klas są wykonywane w kolejności, w jakiej zostały zdefiniowane (odgórnie, podobnie jak proste inicjalizatory zmiennych), gdy klasa jest ładowana (w rzeczywistości, gdy jest rozwiązana, ale to jest techniczny aspekt).

Inicjalizatory instancji

Są wykonywane w kolejności określonej w momencie utworzenia instancji klasy, bezpośrednio przed kod konstruktora jest wykonywany natychmiast po wywołaniu super konstruktora.

Jeśli usuniesz static z int a, stanie się zmienną instancyjną, do której nie masz dostępu z bloku inicjalizacji statycznej. Nie uda się skompilować z błędem "niestatyczna zmienna a nie może być odwołana ze statycznego kontekstu".

Jeśli usuniesz również {[0] } z bloku inicjalizacji, staje się on inicjalizatorem instancji i tak {[1] } jest inicjalizowany w Budownictwo.

 356
Author: Lawrence Dol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-09 12:21:05

Uff! czym jest inicjalizacja statyczna?

Inicjalizacja statyczna jest static {} blokiem kodu wewnątrz klasy java i jest uruchamiana tylko jeden raz przed wywołaniem konstruktora lub głównej metody.

OK! Powiedz mi więcej...

  • jest blokiem kodu static { ... } wewnątrz dowolnej klasy java. i wykonywane przez maszynę wirtualną po wywołaniu klasy.
  • żadne return instrukcje nie są obsługiwane.
  • żadne argumenty nie są wspierane.
  • nie this lub super są obsługiwane.

Hmm gdzie mogę go użyć?

Może być używany wszędzie, gdzie czujesz się dobrze :) to proste. Ale widzę, że większość czasu jest używany podczas wykonywania połączenia z bazą danych, API init, logowania i itp.

Nie szczekaj! gdzie jest przykład?

package com.example.learnjava;

import java.util.ArrayList;

public class Fruit {

    static {
        System.out.println("Inside Static Initializer.");

        // fruits array
        ArrayList<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Orange");
        fruits.add("Pear");

        // print fruits
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        System.out.println("End Static Initializer.\n");
    }

    public static void main(String[] args) {
        System.out.println("Inside Main Method.");
    }
}

Wyjście???

Wewnątrz Statycznego Inicjalizatora.

Jabłko

Pomarańczowy

Gruszka

Zakończ Inicjalizację Statyczną.

Inside Main Metoda.

Mam nadzieję, że to pomoże!
 141
Author: Madan Sapkota,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-24 05:10:18

Blok static jest "inicjalizatorem statycznym".

Jest wywoływana automatycznie, gdy klasa jest ładowana i nie ma innego sposobu na jej wywołanie(nawet przez odbicie).

Ja osobiście używałem go tylko przy pisaniu kodu JNI:
class JNIGlue {
    static {
        System.loadLibrary("foo");
    }
}
 51
Author: Alnitak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-13 15:18:24

To jest bezpośrednio z http://www.programcreek.com/2011/10/java-class-instance-initializers/

1. Zlecenie Wykonania

Spójrz na następujące zajęcia, czy wiesz, która z nich zostanie wykonana pierwsza?

public class Foo {

    //instance variable initializer
    String s = "abc";

    //constructor
    public Foo() {
        System.out.println("constructor called");
    }

    //static initializer
    static {
        System.out.println("static initializer called");
    }

    //instance initializer
    {
        System.out.println("instance initializer called");
    }

    public static void main(String[] args) {
        new Foo();
        new Foo();
    }
}

Wyjście:

Inicjalizator statyczny o nazwie

Inicjalizacja instancji o nazwie

Konstruktor zwany

Inicjalizacja instancji o nazwie

Konstruktor zwany

2. Jak zrobić instancję Java inicjalizator działa?

Przykład inicjujący powyżej zawiera instrukcję println. Aby zrozumieć, jak to działa, możemy traktować to jako instrukcję przypisania zmiennej, np. b = 0. Może to sprawić, że bardziej oczywiste będzie zrozumienie.

Zamiast

int b = 0, możesz napisać

int b;
b = 0;

Dlatego inicjalizatory instancji i inicjalizatory zmiennych instancji są prawie takie same.

3. Kiedy inicjalizatory instancji są przydatne?

Użycie inicjalizatorów instancji jest rzadko, ale nadal może być użyteczną alternatywą dla inicjalizatorów zmiennych instancji, Jeśli:

  1. Kod inicjujący musi obsługiwać wyjątki
  2. wykonaj obliczenia, których nie można wyrazić za pomocą inicjalizatora zmiennej instancji.

Oczywiście, taki kod można zapisać w konstruktorach. Ale jeśli klasa ma wiele konstruktorów, będziesz musiał powtórzyć kod w każdym konstruktorze.

Z inicjalizatorem instancji, możesz po prostu napisać kod raz, a to być wykonywane bez względu na to, jaki konstruktor zostanie użyty do wytworzenia obiektu. (Myślę, że to tylko pojęcie i nie jest często używane.)

Innym przypadkiem, w którym inicjalizatory instancji są użyteczne, są anonimowe klasy wewnętrzne, które nie mogą deklarować żadnych konstruktorów. (Czy to będzie dobre miejsce na umieszczenie funkcji logowania?)

Dzięki Derheinowi.

Należy również zauważyć, że anonimowe klasy implementujące interfejsy [1] nie mają konstruktorów. Dlatego inicjalizatory instancji są potrzebne do wykonywanie dowolnych wyrażeń w czasie budowy.

 29
Author: Alexei Fando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 12:29:43

"final" gwarantuje, że zmienna musi być zainicjalizowana przed końcem kodu inicjującego obiekt. Podobnie" static final " gwarantuje, że zmienna zostanie zainicjalizowana przez koniec kodu inicjalizacyjnego klasy. Pominięcie "static" w kodzie inicjalizacyjnym zamienia go w kod inicjalizacyjny obiektu; w ten sposób zmienna nie spełnia już swoich gwarancji.

 12
Author: DJClayworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-02 20:36:31

Nie będziesz zapisywał kodu do statycznego bloku, który musi być wywoływany w dowolnym miejscu Twojego programu. Jeśli celem kodu jest wywołanie, musisz umieścić go w metodzie.

Możesz pisać statyczne bloki inicjalizacji, aby zainicjować statyczne zmienne, gdy klasa jest ładowana, ale ten kod może być bardziej złożony..

Statyczny blok inicjalizacji wygląda jak metoda bez nazwy, bez argumentów i bez typu zwracanego. Skoro nigdy tego nie nazywasz, to nie potrzebuje imienia. Jedyny raz jego wywołane jest, gdy maszyna wirtualna ładuje klasę.

 6
Author: Vincent Ramdhanie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-02 20:35:20

Gdy programista używa bloku inicjalizatora, kompilator Javy kopiuje inicjalizator do każdego konstruktora bieżącej klasy.

Przykład:

Następujący kod:

class MyClass {

    private int myField = 3;
    {
        myField = myField + 2;
        //myField is worth 5 for all instance
    }

    public MyClass() {
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }


    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

Jest równoważne:

class MyClass {

    private int myField = 3;

    public MyClass() {
        myField = myField + 2;
        myField = myField * 4;
        //myField is worth 20 for all instance initialized with this construtor
    }

    public MyClass(int _myParam) {
        myField = myField + 2;
        if (_myParam > 0) {
            myField = myField * 4;
            //myField is worth 20 for all instance initialized with this construtor
            //if _myParam is greater than 0
        } else {
            myField = myField + 5;
            //myField is worth 10 for all instance initialized with this construtor
            //if _myParam is lower than 0 or if _myParam is worth 0
        }
    }

    public void setMyField(int _myField) {
        myField = _myField;
    }


    public int getMyField() {
        return myField;
    }
}

public class MainClass{

    public static void main(String[] args) {
        MyClass myFirstInstance_ = new MyClass();
        System.out.println(myFirstInstance_.getMyField());//20
        MyClass mySecondInstance_ = new MyClass(1);
        System.out.println(mySecondInstance_.getMyField());//20
        MyClass myThirdInstance_ = new MyClass(-1);
        System.out.println(myThirdInstance_.getMyField());//10
    }
}

Mam nadzieję, że mój przykład zostanie zrozumiany przez deweloperów.

 6
Author: cardman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 18:52:17

Statyczny blok kodu może być użyty do tworzenia instancji lub inicjalizacji zmiennych klasy (w przeciwieństwie do zmiennych obiektu). Deklarowanie statyczne" a " oznacza, że jest to tylko jedno wspólne dla wszystkich obiektów testowych, a statyczny blok kodu inicjalizuje "a" tylko raz, gdy Klasa testowa jest ładowana po raz pierwszy, bez względu na to, ile obiektów testowych zostało utworzonych.

 4
Author: Paul Tomblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-02 20:34:43

Słowo kluczowe statyczne może być używane z klasą, zmienną, metodą i blokiem. Członkowie statyczni należą do klasy, a nie do konkretnej instancji, co oznacza, że jeśli uczynisz członka statycznym, możesz uzyskać do niego dostęp bez obiektu. Przykład:

Tutaj mamy statyczną metodę myStatic (), możemy wywołać tę metodę bez żadnego obiektu, ponieważ kiedy uczynimy member statycznym, staje się on poziomem klasy. Jeśli usuniemy słowo kluczowe static i uczynimy je niestatycznymi, musimy stworzyć obiekt klasy, aby call it

Statyczne elementy są wspólne dla wszystkich instancji (obiektów) klasy, ale niestatyczne elementy są oddzielne dla każdej instancji klasy.

class SimpleStaticExample {
//static method
static void myStatic()
{
    System.out.println("my Static Method");
}

public static void main(String[] args)
{
      /* You can see that we are calling this
       * method without creating any object. 
       */
       myStatic();
 }
}

Wyjście: moja metoda statyczna

 0
Author: Mahendra Sri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-20 04:58:40