en methoden in de JVM

1. Overzicht

De JVM gebruikt twee onderscheidende methoden om objectinstanties en klassen te initialiseren.

In dit korte artikel gaan we zien hoe de compiler en runtime de en methoden voor initialisatiedoeleinden.

2. Initialisatiemethoden voor instanties

Laten we beginnen met een eenvoudige objecttoewijzing en -toewijzing:

Object obj = nieuw object ();

Als we dit fragment compileren en de bytecode ervan bekijken via javap -c, we zullen zoiets zien als:

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

Om het object te initialiseren, de JVM roept een speciale methode aan met de naam .In JVM-jargon is deze methode een methode voor het initialiseren van een instantie. Een methode is een instantie-initialisatie als en alleen als:

  • Het wordt gedefinieerd in een klas
  • Zijn naam is <init>
  • Het keert terug leegte

Elke klasse kan nul of meer initialisatiemethoden voor instanties hebben. Deze methoden komen meestal overeen met constructeurs in op JVM gebaseerde programmeertalen zoals Java of Kotlin.

2.1. Constructors en instantie-initialisatieblokken

Om beter te begrijpen hoe de Java-compiler constructors vertaalt naar , laten we eens kijken naar een ander voorbeeld:

openbare klasse Persoon {privé String firstName = "Foo"; // private String lastName = "Bar"; // // {System.out.println ("Initialiseren ..."); } // public Person (String firstName, String lastName) {this.firstName = firstName; this.lastName = achternaam; } // openbare persoon () {}}

Dit is de bytecode voor deze klasse:

publiek persoon (java.lang.String, java.lang.String); Code: 0: aload_0 1: invokespecial # 1 // Method java / lang / Object. "" :() V 4: aload_0 5: ldc # 7 // String Foo 7: putfield # 9 // Veld voornaam: Ljava / lang /Draad; 10: aload_0 11: ldc # 15 // String Bar 13: putfield # 17 // Veld achternaam: Ljava / lang / String; 16: getstatic # 20 // Field java / lang / System.out: Ljava / io / PrintStream; 19: ldc # 26 // String initialiseren ... 21: invokevirtual # 28 // Methode java / io / PrintStream.println: (Ljava / lang / String;) V 24: aload_0 25: aload_1 26: putfield # 9 // Veld voornaam: Ljava / lang / String; 29: aload_0 30: aload_2 31: putfield # 17 // Veld achternaam: Ljava / lang / String; 34: terug

Hoewel de constructor- en initialisatieblokken in Java gescheiden zijn, bevinden ze zich in dezelfde instantie-initialisatiemethode op bytecodeniveau. Dit is in feite methode:

  • Initialiseert eerst het Voornaam en achternaam velden (index 0 tot 13)
  • Vervolgens wordt er iets naar de console afgedrukt als onderdeel van het instantie-initialisatieblok (index 16 tot en met 21)
  • En tot slot werkt het de instantievariabelen bij met de constructorargumenten

Als we een Persoon als volgt:

Persoon persoon = nieuwe persoon ("Brian", "Goetz");

Dit vertaalt zich dan naar de volgende bytecode:

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

Deze keer belt JVM een andere methode met een handtekening die overeenkomt met de Java-constructor.

De belangrijkste afweging hier is dat de constructors en andere instantie-initialisatieprogramma's gelijk zijn aan de methode in de JVM-wereld.

3. Methoden voor klasseninitialisatie

In Java zijn statische initialisatieblokken handig als we iets op klassenniveau gaan initialiseren:

openbare klasse Persoon {privé statische laatste Logger LOGGER = LoggerFactory.getLogger (Person.class); // // static {System.out.println ("Statisch initialiseren ..."); } // weggelaten}

Wanneer we de voorgaande code compileren, vertaalt de compiler het statische blok naar een klasse-initialisatiemethode op bytecodeniveau.

Simpel gezegd, een methode is een klasse-initialisatie als en slechts als:

  • Zijn naam is
  • Het keert terug leegte

Daarom is de enige manier om een methode in Java is om statische velden en statische blokinitializers te gebruiken.

JVM roept het de eerste keer dat we de bijbehorende klasse gebruiken. Daarom, de aanroep gebeurt tijdens runtime en we kunnen de aanroep niet zien op bytecode-niveau.

4. Conclusie

In dit korte artikel zagen we het verschil tussen en methoden in de JVM. De methode wordt gebruikt om objectinstanties te initialiseren. Ook roept de JVM de methode om een ​​klasse te initialiseren wanneer dat nodig is.

Om beter te begrijpen hoe initialisatie werkt in de JVM, wordt het ten zeerste aanbevolen om de JVM-specificatie te lezen.


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