og metoder i JVM

1. Oversigt

JVM bruger to karakteristiske metoder til at initialisere objektforekomster og klasser.

I denne hurtige artikel vil vi se, hvordan compileren og runtime bruger og metoder til initialiseringsformål.

2. Instans initialiseringsmetoder

Lad os starte med en ligetil objektallokering og tildeling:

Objekt obj = nyt objekt ();

Hvis vi kompilerer dette uddrag og kigger på dets bytecode via javap -c, vi ser noget som:

0: ny # 2 // klasse java / lang / Objekt 3: dup 4: invokespecial # 1 // Metode java / lang / Objekt. "" :() V 7: astore_1

For at initialisere objektet, JVM kalder en særlig metode navngivet .I JVM-jargon er denne metode en instans initialiseringsmetode. En metode er en instansinitialisering, hvis og kun hvis:

  • Det er defineret i en klasse
  • Dens navn er <init>
  • Det vender tilbage ugyldig

Hver klasse kan have nul eller flere initialiseringsmetoder. Disse metoder svarer normalt til konstruktører i JVM-baserede programmeringssprog såsom Java eller Kotlin.

2.1. Konstruktions- og instansinitialiseringsblokke

For bedre at forstå, hvordan Java-kompilatoren oversætter konstruktører til , lad os overveje et andet eksempel:

public class Person {private String firstName = "Foo"; // private String lastName = "Bar"; // // {System.out.println ("Initialiserer ..."); } // offentlig person (streng fornavn, streng efternavn) {this.firstName = fornavn; this.lastName = efternavn; } // offentlig person () {}}

Dette er bytecode for denne klasse:

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 /Snor; 10: aload_0 11: ldc # 15 // String Bar 13: putfield # 17 // Feltets efternavn: Ljava / lang / String; 16: getstatic # 20 // Field 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 // Felt efternavn: Ljava / lang / String; 34: retur

Selvom konstruktøren og initialiseringsblokkene er adskilte i Java, er de i samme instans initialiseringsmetode på bytecode-niveau. Faktisk er dette metode:

  • Initialiserer først fornavn og efternavn felter (indeks 0 til 13)
  • Derefter udskriver det noget til konsollen som en del af instansens initialiseringsblok (indeks 16 til 21)
  • Og endelig opdaterer den instansvariablerne med konstruktørargumenterne

Hvis vi opretter en Person som følger:

Person person = ny person ("Brian", "Goetz");

Derefter oversættes dette til følgende bytecode:

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 gang ringer JVM til en anden metode med en signatur svarende til Java-konstruktøren.

Det vigtigste takeaway her er, at konstruktørerne og andre instansinitialiserere svarer til metode i JVM-verdenen.

3. Klasseinitialiseringsmetoder

I Java er statiske initialiseringsblokke nyttige, når vi skal initialisere noget på klasseniveau:

offentlig klasse Person {privat statisk endelig Logger LOGGER = LoggerFactory.getLogger (Person.class); // // statisk {System.out.println ("Statisk initialisering ..."); } // udeladt}

Når vi kompilerer den foregående kode, oversætter compileren den statiske blok til en klasseinitialiseringsmetode på bytekodeniveau.

Enkelt sagt er en metode en klasseinitialisering, hvis og kun hvis:

  • Dens navn er
  • Det vender tilbage ugyldig

Derfor er den eneste måde at generere en metode i Java er at bruge statiske felter og statiske blokinitialiserere.

JVM påberåber sig første gang vi bruger den tilsvarende klasse. Derfor er den påkaldelse sker ved runtime, og vi kan ikke se påkaldelsen på bytecode-niveau.

4. Konklusion

I denne hurtige artikel så vi forskellen mellem og metoder i JVM. Det metoden bruges til at initialisere objektforekomster. Også JVM påberåber sig metode til at initialisere en klasse, når det er nødvendigt.

For bedre at forstå, hvordan initialisering fungerer i JVM, anbefales det stærkt at læse JVM-specifikationen.


$config[zx-auto] not found$config[zx-overlay] not found