Vorwort
In Java muss ein Objekt korrekt initialisiert werden, bevor es verwendet werden kann, was durch die Java -Spezifikation festgelegt wird.
Automatische Initialisierung (Standard)
Alle grundlegenden Datenmitglieder einer Klasse werden initialisiert. Führen Sie das folgende Beispiel aus, um diese Standardwerte anzuzeigen:
Klasse Standard {boolean t; Char C; Byte B; kurz S; int i; lange l; float f; doppelt d; public void show () {System.out.println ("Grundtyp-Initialisierungswert/n" + "boolean <------>" + t + "/n" + "char <------>" + c + "/n" + "Byte <------ l + "/n" + "float <------>" + f + "/n" + "double <------>" + d + "/n"); }} public class initValue {public static void main (String [] args) {Standard d = new default (); d.show (); }}【Betriebsergebnisse】:
Grundtyp -Initialisierungswert
boolean <------> Falsch
char <----->
Byte <------> 0
kurz <------> 0
int <------> 0
lang <------> 0
Float <------> 0.0
Doppel <------> 0.0
Wo ist der Standardwert des Zeichenentyps null.
Für nicht primitive Datentypen wird auch das Handle des Objekts initialisiert:
Klasse Person {privater Zeichenfolge Name; // Setter} Klasse Standard {Person p; public void show () {System.out.println ("Person <---->" + p); }} public class initValue {public static void main (String [] args) {Standard d = new default (); d.show (); }}【Betriebsergebnisse】:
Person <------> null
Es ist ersichtlich, dass der Griffinitialisierungswert null ist. Dies bedeutet, dass, wenn eine ähnliche Methode wie p.setName aufgerufen wird, ohne einen Initialisierungswert für P anzugeben, eine Ausnahme auftritt.
Vorschrifteninitialisierung
Wenn Sie selbst einen Anfangswert selbst zuweisen müssen, können Sie einen Wert zuweisen, während Sie die Variable definieren.
Klasse Standard {boolean t = true; char c = 'a'; Byte B = 47; kurz S = 0xff; int i = 24; lang L = 999; float f = 1,2f; Doppel d = 1,732; public void show () {system.out.println ("boolean <------>" + t + "/n" + "char <------>" + c + "/n" + "byte <------->" + b + "/n" + "kurz <------- "float <------>" + f + "/n" + "double <------>" + d + "/n"); }} public class initValue {public static void main (String [] args) {Standard d = new default (); d.show (); }}Es kann sogar auf eine Weise initialisiert werden;
Klasse Person {int i = set (); // ...}Diese Methoden können auch unabhängige Variablen verwenden:
Klasse Person {int i; int j = set (i); // ...} Erbauerinitialisierung
Der Vorteil der Initialisierung eines Bauunternehmens besteht darin, dass der Initialisierungswert während der Laufzeit bestimmt werden kann. Zum Beispiel:
Klasse Person {int age; Person () {Age = 89; }}Das Alter wird zuerst auf 0 initialisiert und dann zu 89. Dies gilt für alle Grundtypen sowie für Handles zu Objekten.
Initialisierungsreihenfolge
In einer Klasse wird die Reihenfolge der Initialisierung durch die Reihenfolge bestimmt, in der Variablen innerhalb der Klasse definiert werden. Auch wenn die Variablendefinitionen weitgehend in der Mitte der Methodendefinition verteilt sind, wird die Variable weiterhin initialisiert, bevor eine Methode (einschließlich des Konstruktors) aufgerufen wird. Zum Beispiel:
Klasse PET {PET (int ARTER) {System.out.println ("PET (" + AGE + ")"); }} Klasse Person {PET T1 = neues Haustier (1); Person () {System.out.println ("--- Person () ---"); T3 = neues Haustier (33); } PET T2 = neues Haustier (2); void show () {System.out.println ("show ----- running"); } Pet t3 = new Pet (3);} öffentliche Klasse Orderofinitialisierung {public static void main (String [] args) {Person p = new Person (); P.Show (); }}【Betriebsergebnisse】:
Haustier (1)
Haustier (2)
Haustier (3)
--Person()---
Haustier (33) <br/>
Show ----- Laufen
Obwohl die Definitionen von T1, T2 und T3 in der gesamten Klasse sind, wird im obigen Beispiel die Reihenfolge der Initialisierung durch die Definitionsreihenfolge von T1, T2 und T3 bestimmt (Änderung von T1, T2 und T3 selbst, um das Ergebnis zu sehen), und die Initialisierung hat Vorrang vor der Herstellung der Bauherren. Wenn der Personenbauer aufgerufen wird, wird T3 neu initialisiert.
Initialisierung statischer Daten
Wenn die Daten statisch sind, wird der gleiche Prozess durchgeführt. Wenn es sich um einen primitiven Typ handelt und nicht initialisiert wird, erhält er automatisch seinen eigenen Standardwert des primitiven Typs. Wenn es sich um ein Objekt handelt, erhält es einen Nullwert, es sei denn, ein Objekt wird erstellt und damit verbunden. Wenn es zur Definitionszeit initialisiert wurde, unterscheidet sich die Methode vom nicht statischen Wert, da static nur einen Speicherbereich hat. Zum Beispiel:
Klasse Bowl {Bowl (int Marker) {System.out.println ("Bowl (" + Marker + ")"); } void f (int marker) {System.out.println ("f (" + marker + ")"); }} Klassentabelle {static Bowl B1 = New Bowl (1); Table () {System.out.println ("table ()"); b2.f (1); } void f2 (int marker) {System.out.println ("f2 (" + marker + ")"); } statische Schüssel B2 = neue Schüssel (2);} Klassenschrank {Schüssel B3 = neue Schüssel (3); statische Schüssel B4 = neue Schüssel (4); Cupboard () {system.out.println ("cuppboard ()"); b4.f (2); } void f3 (int marker) {System.out.println ("f3 (" + marker + ")"); } static Bowl B5 = New Bowl (5);} öffentliche Klasse staticInitialisierung {public static void main (String [] args) {System.out.println ("neuer Schrank () in Main"); neuer Schrank (); System.out.println ("Neue Schrank () in Main erstellen"); neuer Schrank (); t2.f2 (1); t3.f3 (1); } statische Tabelle T2 = neue Tabelle (); statischer Schrank T3 = neuer Schrank ();}【Betriebsergebnisse】:
Schüssel (1)
Schüssel (2)
Tisch()
F (1)
Schüssel (4)
Schüssel (5)
Schüssel (3)
Schrank()
F (2)
Erstellen neuer Schrank () in Main
Schüssel (3)
Schrank()
F (2)
Erstellen neuer Schrank () in Main
Schüssel (3)
Schrank()
F (2)
F2 (1)
F3 (1)
Statische Codeblöcke
Java ermöglicht es, dass andere statische Initialisierungsarbeiten in einen speziellen Codeblock in der Klasse unterteilt werden. Dieser Codeblock befindet sich in Form eines statischen Schlüsselworts, gefolgt von einer Methodenkörper, die als statischer Codeblock bezeichnet wird. Ein statischer Codeblock wird nur ausgeführt, wenn das Objekt dieser Klasse zum ersten Mal generiert wird oder auf das statische Mitglied dieser Klasse zum ersten Mal zugegriffen wird. Zum Beispiel:
Klasse Person {Person (int age) {System.out.println ("Person (" + älter + ")"); } void f (int age) {System.out.println ("f (" + älter + ")"); }} Klasse Personen {statische Person p1; statische Person P2; static {p1 = neue Person (1); P2 = neue Person (2); } Persons () {System.out.println ("persons ()"); }} public class explizitstatic {public static void main (String [] args) {System.out.println ("Inside main ()"); Persons.p1.f (18); // 1} statische Personen x = neue Personen (); // 2 statische Personen y = new persons (); // 2}Wenn Sie auf das statische Objekt P1 in einer 1 -mit 1 gekennzeichneten Zeile zugreifen, oder wenn Zeile 1 kommentiert wird und Zeile 2 nicht kommentiert wird, wird das statische Initialisierungsmodul für Personen ausgeführt. Wenn sowohl 1 als auch 2 kommentiert werden, wird der für Personen verwendete statische Codeblock nicht ausgeführt.
Die Reihenfolge statischer Eigenschaften und statischer Code -Blockausführung
Klasse Person {Person (int age) {System.out.println ("Person ("+älter+")"); }} Klasse Personen {statische Person p = neue Person (2); // 1 static {p = neue Person (3); } statische Person p = neue Person (2); // 2} öffentliche Klasse CompStaticInit {public static void main (String [] args) {} statische Personen x = new persons ();}Gemäß der Analyse der Ergebnisse von Annotation 1, die 2 und Annotation 2 beibehalten, ist es zu erkennen, dass die Reihenfolge der Ausführung statischer Eigenschaften und statischer Codeblöcke von der Reihenfolge der Codierung abhängt. Wer vor uns ist, wird zuerst ausgeführt.
Initialisierung nicht statischer Eigenschaften
Klasse Animal {Animal (int age) {System.out.println ("Animal (" + älter + ")"); } void f (int age) {System.out.println ("f (" + älter + ")"); }} öffentliche Klasse NotstaticInit {Animal A1; Tier A2; {A1 = neues Tier (1); A2 = neues Tier (2); System.out.println ("A1 & A2 initialisiert"); } NotStaticInit () {System.out.println ("NotstaticInit"); } public static void main (String [] args) {System.out.println ("inside main ()"); NotStaticInit x = new NotstaticInit (); }}Ähnlich wie bei statischen Codeblöcken hängt die Initialisierungsreihenfolge von anonymen Codeblöcken mit nicht statischen Eigenschaften von der Codierungsreihenfolge ab.
Vererbter Objektinitialisierungsprozess
Klasse Insekt {int i = 1; int j; Insect () {prt ("i =" + i + ", j =" + j); J = 2; } static int x1 = prt ("static Insect.x1 initialisiert"); static int prt (String s) {System.out.println (s); Rückkehr 3; }} public class Käfer erweitert Insekt {int k = prt ("BeEKLT.K initialisiert"); Peetle () {prt ("k =" + k); prt ("j =" + j); } static int x2 = prt ("static Bootle.x2 initialisiert"); static int prt (String s) {System.out.println (s); Rückkehr 4; } public static void main (String [] args) {prt ("Käferkonstruktor"); Käfer B = neuer Käfer (); }}【Betriebsergebnisse】:
statisches Insekt.x1 initialisiert
static Bootle.x2 initialisiert
Käferkonstruktor
i = 1, j = 0
Beeklt.k initialisiert
K = 4
J = 2
Das erste, was beim Ausführen von Java auf Käfer passiert, ist der Lader, der diese Klasse draußen findet. Während des Ladevorgangs entdeckt der Lader eine Basisklasse, so dass er entsprechend geladen wird. Dieser Prozess wird unabhängig davon durchgeführt, ob das Objekt der zugrunde liegenden Klasse generiert wird oder nicht. Wenn die Basisklasse eine andere Basisklasse enthält, wird die andere Basisklasse geladen und so weiter. Führen Sie als nächstes die statische Initialisierung in der Stammbasisklasse durch, dann in der nächsten Ableitungsklasse und so weiter aus. Dies liegt daran, dass die Initialisierung der Derivatklasse von der Initialisierung der zugrunde liegenden Klassenmitglieder abhängt.
Wenn alle Klassen geladen werden, können Objekte erstellt werden. Zunächst werden alle grundlegenden Datentypen in diesem Objekt auf ihre Standardwerte gesetzt und das Objektgegriff auf null gesetzt. Führen Sie dann den Erbauer der Basisklasse aus. Diese Situation erfolgt automatisch ( super(), und der Erbauer der Basisklasse kann auch über Super angegeben werden). Nachdem der Basisklassenbauer abgeschlossen ist, werden die abgeleiteten Klasseninstanzvariablen in ihrer ursprünglichen Reihenfolge initialisiert, und die verbleibenden Körperteile des Bauherrn werden ausgeführt.
Fassen Sie den Prozess der Objekterstellung zusammen:
Die statische Ausführung wird nur ausgeführt, wenn die Klasse geladen ist und nur einmal;
Nichtstatik wird nur ausgeführt, wenn es so weitergeht, und führt jedes Mal aus, wenn ein Objekt erstellt wird.
Die statische Ausführung wird vor nicht statischer Ausführung durchgeführt, und die statische Basisklasse geht der statischen Ausführung gegenüber Derivatklassen voraus.
Die Ausführungseigenschaften statischer Eigenschaften und statischer Codeblöcke hängen von ihrer Position in der Klasse ab und wer sie zuerst ausführt.
Die Ausführungsreihenfolge nicht statischer Eigenschaften und Konstruktorblöcke hängt von ihrer Position in der Klasse ab und wer vor ihnen ausführt.
Zusammenfassen
Durch die obige Einführung haben wir ein Verständnis für verschiedene Möglichkeiten, Objekte in Java zu initialisieren und den Initialisierungscode auszuführen, und stellt auch die Situationen ein, die wir möglicherweise nicht initialisierte Variablen verwenden. Nachdem Sie ein detailliertes Verständnis dieser Probleme erhalten haben, können Sie einige Risiken bei der Codierung vermeiden, um sicherzustellen, dass ein Objekt vollständig initialisiert wird, bevor es sichtbar wird.