og metoder i JVM
1. Oversikt
JVM bruker to særegne metoder for å initialisere objektforekomster og klasser.
I denne raske artikkelen skal vi se hvordan kompilatoren og kjøretiden bruker og metoder for initialiseringsformål.
2. Instans initialiseringsmetoder
La oss starte med en enkel objektallokering og oppgave:
Objekt obj = nytt objekt ();
Hvis vi kompilerer denne kodebiten og ser på bytekoden via javap -c, får vi se noe sånt som:
0: ny # 2 // klasse java / lang / Object 3: dup 4: invokespecial # 1 // Method java / lang / Object. "" :() V 7: astore_1
Å initialisere objektet, JVM kaller en spesiell metode som heter .I JVM-sjargong er denne metoden en metode for initialiseringsinstans. En metode er en initialisering av en forekomst hvis og bare hvis:
- Det er definert i en klasse
- Navnet dens er <init>
- Det kommer tilbake tomrom
Hver klasse kan ha null eller flere initialiseringsmetoder. Disse metodene tilsvarer vanligvis konstruktører i JVM-baserte programmeringsspråk som Java eller Kotlin.
2.1. Konstruktører og initialiseringsblokker
For å bedre forstå hvordan Java-kompilatoren oversetter konstruktører til , la oss vurdere et annet eksempel:
offentlig klasse Person {private String firstName = "Foo"; // private String lastName = "Bar"; // // {System.out.println ("Initialiserer ..."); } // offentlig person (streng fornavn, streng etternavn) {this.firstName = fornavn; this.lastName = etternavn; } // offentlig person () {}}
Dette er bytekoden for denne klassen:
offentlig person (java.lang.String, java.lang.String); Kode: 0: aload_0 1: invokespecial # 1 // Method java / lang / Object. "" :() V 4: aload_0 5: ldc # 7 // String Foo 7: putfield # 9 // Field firstName: Ljava / lang / String; 10: aload_0 11: ldc # 15 // String Bar 13: putfield # 17 // Field lastName: Ljava / lang / String; 16: getstatic # 20 // Felt java / lang / System.out: Ljava / io / PrintStream; 19: ldc # 26 // String Initializing ... 21: invokevirtual # 28 // Method java / io / PrintStream.println: (Ljava / lang / String;) V 24: aload_0 25: aload_1 26: putfield # 9 // Feltets fornavn: Ljava / lang / String; 29: aload_0 30: aload_2 31: putfield # 17 // Feltets etternavn: Ljava / lang / String; 34: retur
Selv om konstruktøren og initialiseringsblokkene er separate i Java, er de i samme tilfelle initialiseringsmetode på bytekode-nivå. Faktisk, dette metode:
- Initialiserer først fornavn og etternavn felt (indeks 0 til 13)
- Deretter skriver den ut noe til konsollen som en del av forekomstinitialiseringsblokken (indeks 16 til 21)
- Og til slutt oppdaterer den forekomstvariablene med konstruktørargumentene
Hvis vi lager en Person som følger:
Personperson = ny person ("Brian", "Goetz");
Da oversettes dette til følgende bytekode:
0: ny # 7 // klasse 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
Denne gangen ringer JVM til en annen metode med en signatur som tilsvarer Java-konstruktøren.
Nøkkelen til takeaway her er at konstruktørene og andre initialiseringsinstanser tilsvarer metode i JVM-verdenen.
3. Klasseinitialiseringsmetoder
I Java er statiske initialiseringsblokker nyttige når vi skal initialisere noe på klassenivå:
public class Person {private static final Logger LOGGER = LoggerFactory.getLogger (Person.class); // // statisk {System.out.println ("Statisk initialisering ..."); } // utelatt}
Når vi kompilerer den forrige koden, oversetter kompilatoren den statiske blokken til en klasseinitialiseringsmetode på bytekodenivå.
Enkelt sagt er en metode en klasseinitialisering hvis og bare hvis:
- Navnet dens er
- Det kommer tilbake tomrom
Derfor er den eneste måten å generere en metoden i Java er å bruke statiske felt og statiske blokkeringsinitialiserere.
JVM påkaller første gang vi bruker tilsvarende klasse. derfor påkalling skjer på kjøretid, og vi kan ikke se påkallingen på bytecode-nivå.
4. Konklusjon
I denne raske artikkelen så vi forskjellen på og metoder i JVM. De metoden brukes til å initialisere objektforekomster. Også, JVM påkaller metode for å initialisere en klasse når det er nødvendig.
For bedre å forstå hvordan initialisering fungerer i JVM, anbefales det sterkt å lese JVM-spesifikasjonen.