Patrzę na poniższy kod i znalazłem coś trochę dziwnego:
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("y ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("g ");
}
static {
System.out.print("x ");
}
}
Spodziewałbym się, że spowoduje to błąd kompilacji, ponieważ znak System.out
z "y" nie należy do deklaracji metody, tylko do { }
. Dlaczego to jest ważne? Nie rozumiem, jak ten kod miałby lub powinien zostać wywołany.
Po uruchomieniu tego generuje x y c g
również, dlaczego static { }
get jest wywoływane przed konstruktorem sekwencji?
źródło
the code is copied into the beginning of each constructor of the class
- to jest niepoprawne. Powiedzmy, że konstruktor zaczyna się odsuper("x ");
, super konstruktor wykona przed jakimikolwiek blokami inicjalizacyjnymi.To nie jest metoda, ale blok inicjalizacji .
Zostanie wykonany przed wywołaniem konstruktora. Podczas
jest statycznym blokiem inicjalizacyjnym, który jest wykonywany, gdy klasa jest ładowana przez program ładujący klasy.
Więc kiedy uruchamiasz swój kod
1. Klasa jest ładowana przez program ładujący klasy, więc wykonywany jest statyczny blok inicjalizacyjny.
Wyjście: wypisywane jest x
2. Obiekt jest tworzony tak, że wykonywany jest blok inicjalizacyjny, a następnie wywoływany jest konstruktor
Wyjście: drukowane jest y, a następnie c
3. Wywoływana jest metoda główna, która z kolei wywołuje metodę go.
Wyjście: drukowane jest g
Końcowy wynik: xycg
To może pomóc http://blog.sanaulla.info/2008/06/30/initialization-blocks-in-java/
źródło
To blok inicjalizacji wystąpienia, po którym następuje blok inicjalizacji statycznej .
jest wywoływana podczas tworzenia instancji klasy.
jest wywoływana, gdy klasa jest ładowana przez program ładujący klasy. Więc kiedy to zrobisz
klasa zostaje załadowana, więc jest wykonywana
static {}
, następnie wykonuje blok inicjalizacji instancji{}
, następnie wywoływana jest treść konstruktora, a następnie metoda na nowo utworzonej instancji. Ergo wyjściex y c g
.źródło
Jest blokiem statycznym i jest wywoływana podczas ładowania klasy
Jest blokiem inicjalizacyjnym
Możesz mieć wiele bloków inicjalizacyjnych w klasie, w którym to przypadku są one wykonywane w kolejności, w jakiej występują w klasie.
Zauważ, że każdy blok inicjalizacji obecny w klasie jest wykonywany przed konstruktorem.
źródło
jest blokiem inicjalizacyjnym współdzielonym przez klasę (jak wskazuje
static
), który jest wykonywany jako pierwszy.jest blokiem inicjalizacyjnym współdzielonym przez wszystkie obiekty (konstruktory) klasy, który następuje w następnej kolejności.
jest konkretnym konstruktorem dla klasy, która jest wykonywana jako trzecia. Blok inicjalizacji wystąpienia jest wywoływany jako pierwszy za każdym razem, gdy wykonywany jest konstruktor. Dlatego „y” występuje tuż przed „c”.
jest tylko metodą instancji skojarzoną z obiektami zbudowanymi przy użyciu powyższego konstruktora, który jest ostatni.
źródło
Tego rodzaju bloki nazywane są
initializer block
. Jest wykonywany za każdym razem, gdy tworzysz instancjęclass
. W czasie kompilacji ten kod jest przenoszony do każdego konstruktora Twojej klasy.Gdzie jak w przypadku
static initializer
bloku: -jest wykonywany raz, gdy klasa jest ładowana. Zwykle używamy
static
bloku inicjalizatora, gdy inicjalizacjastatic
pola wymaga wielu kroków.źródło
Jest używany jako blok inicjalizacyjny i jest uruchamiany po każdej deklaracji statycznej . Można go użyć, aby upewnić się, że nikt inny nie może utworzyć instancji klasy (w taki sam sposób, w jaki użyłbyś prywatnego konstruktora), jak w przypadku wzorca projektowego Singleton .
źródło
Static blocks
są wykonywane tylko raz, gdy klasa jest ładowana i inicjowana przez środowisko JRE.I
non-static
blok będzie dzwonić za każdym razem, gdy tworzysz nową instancję i to będzie wezwanie tuż przed konstruktora.Jak tutaj stworzyłeś tylko 1
Sequence
tak skonstruowane wystąpienie zostało wywołane ponon-static
blokach, a następnie metoda, która faktycznie jest twoim celem.źródło