és módszerek a JVM-ben

1. Áttekintés

A JVM két megkülönböztető módszert használ az objektumpéldányok és -osztályok inicializálásához.

Ebben a rövid cikkben megnézzük, hogy a fordító és a futásideje hogyan használja a és módszerek az inicializálás céljából.

2. Példák inicializálási módszerei

Kezdjük egy egyszerű objektum-hozzárendeléssel és hozzárendeléssel:

Object obj = new Object ();

Ha összeállítjuk ezt a részletet, és megnézzük a via byte kódját javap -c, valami ilyesmit fogunk látni:

0: new # 2 // java / lang / Object 3: dup 4: invokespecial # 1 // metódus java / lang / Object. "" :() V 7: astore_1

Az objektum inicializálása, a JVM egy speciális módszert hív .A JVM szakzsargonban ez a módszer egy példány inicializálási módszer. A módszer csak akkor inicializálja a példányt, ha:

  • Osztályban van meghatározva
  • A neve <init>
  • Visszatér üres

Minden osztálynak lehet nulla vagy több példánya inicializálási módszer. Ezek a módszerek általában megfelelnek a JVM-alapú programozási nyelvek, például a Java vagy a Kotlin konstruktorainak.

2.1. Konstruktorok és példányok inicializáló blokkjai

Annak érdekében, hogy jobban megértsük, hogyan fordítja le a Java fordító a konstruktorokat vegyünk egy másik példát:

public class Személy {private String keresztnév = "Foo"; // privát karakterlánc vezetéknév = "Bár"; // // {System.out.println ("Inicializálás ..."); } // nyilvános személy (String keresztnév, String vezetéknév) {this.firstName = keresztnév; this.lastName = vezetékNév; } // nyilvános személy () {}}

Ez az osztály bájtkódja:

public Person (java.lang.String, java.lang.String); Kód: 0: aload_0 1: invokespecial # 1 // metódus java / lang / Object. "" :() V 4: aload_0 5: ldc # 7 // String Foo 7: putfield # 9 // Mező keresztneve: Ljava / lang /Húr; 10: aload_0 11: ldc # 15 // String Bar 13: putfield # 17 // Field lastName: Ljava / lang / String; 16: getstatic # 20 // java / lang / System.out mező: Ljava / io / PrintStream; 19: ldc # 26 // Karakterlánc inicializálása ... 21: invokevirtual # 28 // java / io / PrintStream.println módszer: (Ljava / lang / String;) V 24: aload_0 25: aload_1 26: putfield # 9 // Mező firstName: Ljava / lang / String; 29: aload_0 30: aload_2 31: putfield # 17 // Field lastName: Ljava / lang / String; 34: visszatérés

Annak ellenére, hogy a konstruktor és az inicializáló blokkok elkülönülnek a Java-ban, ugyanabban a példányban az inicializálási módszer a bytecode szinten van. Ami azt illeti, ez módszer:

  • Először inicializálja a keresztnév és vezetéknév mezők (0–13 index)
  • Ezután kinyomtat valamit a konzolra a példány inicializáló blokk részeként (16–21. Index)
  • És végül frissíti a példányváltozókat a konstruktor argumentumokkal

Ha létrehozunk egy Személy alábbiak szerint:

Személy személy = új Személy ("Brian", "Goetz");

Akkor ez a következő bájtkódot jelenti:

0: new # 7 // class Person 3: dup 4: ldc # 9 // String Brian 6: ldc # 11 // String Goetz 8: invokespecial # 13 // Method Person. "" :( Ljava / lang / String; Ljava / lang / String;) V 11: astore_1

Ezúttal a JVM hív egy másikat metódus a Java konstruktornak megfelelő aláírással.

A legfontosabb elvitel itt az, hogy a konstruktorok és más példányok inicializálói ekvivalensek a módszer a JVM világában.

3. Osztály inicializálási módszerek

A Java-ban a statikus inicializáló blokkok hasznosak, ha valamit osztályszintűen inicializálni fogunk:

public class Személy {private static final Logger LOGGER = LoggerFactory.getLogger (Személy.osztály); // // statikus {System.out.println ("Statikus inicializálás ..."); } // kihagyva}

Amikor az előző kódot lefordítottuk, a fordító a statikus blokkot osztály inicializálási módszerré fordítja bytecode szinten.

Egyszerűen fogalmazva, a módszer akkor és csak akkor osztályosztályos inicializálás, ha:

  • A neve
  • Visszatér üres

Ezért az egyetlen módja a módszer a Java-ban statikus mezők és statikus blokkok inicializálóinak használata.

A JVM a amikor először használjuk a megfelelő osztályt. Ezért a a meghívás futás közben történik, és a meghívást nem láthatjuk bytecode szinten.

4. Következtetés

Ebben a gyors cikkben láttuk a különbséget és módszerek a JVM-ben. A metódust használnak az objektumpéldányok inicializálására. Ezenkívül a JVM meghívja a módszer az osztály inicializálására, amikor csak szükséges.

Annak érdekében, hogy jobban megértsük, hogyan működik az inicializálás a JVM-ben, nagyon ajánlott elolvasni a JVM specifikációt.