From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100054.html | 437 +++++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100054.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100054.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100054.html b/Master/Reference Architectures and Patterns/hjp5/html/k100054.html new file mode 100644 index 0000000..6ff80bb --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100054.html @@ -0,0 +1,437 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 8 - OOP II: Vererbung, Polymorphismus und statische Elemente +
+
+ + + + +

8.3 Statische Methoden und Membervariablen

+
+ +
+ + + + +

8.3.1 Klassenvariablen

+ +

+Java ist eine konsequent objektorientierte Sprache, in der es weder +globale Funktionen noch globale Variablen gibt. Da es aber mitunter +sinnvoll ist, Eigenschaften zu verwenden, die nicht an Instanzen einer +Klasse gebunden sind, haben die Sprachdesigner das Attribut static +für Methoden und Variablen eingeführt. Eine Variable, die +innerhalb einer Klasse mit dem Attribut static +versehen wurde, nennt man Klassenvariable (oder auch Statische +Variable). Im Gegensatz zu Instanzvariablen, +die immer an ein konkretes Objekt gebunden sind, existieren Klassenvariablen +unabhängig von einem Objekt. + +

+Jede Klassenvariable wird nur einmal angelegt und kann von allen Methoden +der Klasse aufgerufen werden. Da sich alle Methoden die Variable »teilen«, +sind Veränderungen, die eine Instanz vornimmt, auch in allen +anderen Instanzen sichtbar. Klassenvariablen sind daher vergleichbar +mit globalen Variablen, denn ihre Lebensdauer erstreckt sich auf das +gesamte Programm. Namenskollisionen können allerdings nicht auftreten, +denn der Zugriff von außen erfolgt durch Qualifizierung mit +dem Klassennamen in der Form Klassenname.Variablenname. + +

+Ein einfaches Beispiel für die Verwendung von Klassenvariablen +besteht darin, einen Instanzenzähler in eine Klasse einzubauen. +Hierzu wird eine beliebige Klassenvariable eingeführt, die beim +Erzeugen eines Objekts hoch- und beim Zerstören heruntergezählt +wird. Das folgende Beispiel demonstriert das für die Klasse Auto: + + +

+ + + + + +
+ +
+001 /* Testauto.java */
+002 
+003 public class Testauto
+004 {
+005   static private int objcnt = 0;
+006 
+007   public Testauto()
+008   {
+009     ++objcnt;
+010   }
+011 
+012   public void finalize()
+013   {
+014     --objcnt;
+015   }
+016 
+017   public static void main(String[] args)
+018   {
+019     Testauto auto1;
+020     Testauto auto2 = new Testauto();
+021     System.out.println(
+022       "Anzahl Testauto-Objekte: " + Testauto.objcnt
+023     );
+024   }
+025 }
+
+
+Testauto.java
+ +Listing 8.7: Realisierung eines Instanzenzählers mit Klassenvariablen

+ +

+Die Ausgabe des Programms ist: + +

+Anzahl Testauto-Objekte: 1
+
+ + +

+Mit auto2 wurde eine Instanz +der Klasse erzeugt, auto1 ist +dagegen zum Zeitpunkt der Ausgabeanweisung lediglich eine noch nicht +initialisierte Objektreferenz. + + + + +

8.3.2 Konstanten

+ +

+Eine andere Anwendung von Klassenvariablen besteht in der Deklaration +von Konstanten. Dazu wird das static-Attribut +mit dem final-Attribut +kombiniert, um eine unveränderliche Variable mit unbegrenzter +Lebensdauer zu erzeugen: + + +

+ + + + +
+ +
+001 public class Auto
+002 {
+003   private static final double STEUERSATZ = 18.9;
+004 }
+
+
+ +Listing 8.8: Verwendung von Klassenvariablen zur Definition von Konstanten

+

+ + + + + + + + + +
+ +

+Durch die Anwendung von final +wird verhindert, dass der Konstanten STEUERSATZ während der Ausführung +des Programms ein anderer Wert zugewiesen wird. Da Java keinen Präprozessor +enthält und damit keine #define-Anweisung +kennt, ist die beschriebene Methode das einzige Verfahren zur Deklaration +von Konstanten in Java. Die Konvention, Konstantennamen groß +zu schreiben, wurde dabei von C übernommen.

+ + + + +
 Hinweis 
+
+ + + + +

8.3.3 Klassenmethoden

+ +

+Neben Klassenvariablen gibt es in Java auch Klassenmethoden, +d.h. Methoden, die unabhängig von einer bestimmten Instanz existieren. +Sie werden auch als statische Methoden +bezeichnet. Klassenmethoden werden ebenfalls mit Hilfe des static-Attributs +deklariert und - analog zu Klassenvariablen - durch Voranstellen des +Klassennamens aufgerufen. + +

+Da Klassenmethoden unabhängig von konkreten Instanzen ihrer Klasse +existieren, ist ein Zugriff auf Instanzvariablen nicht möglich. +Diese Trennung äußert sich darin, dass Klassenmethoden +keinen this-Zeiger +besitzen. Der Zugriff auf Instanzvariablen und der Aufruf von Instanzmethoden +wird daher schon zur Compile-Zeit als Fehler erkannt. +

+ + + + + + + + + + + +
+ +

+Klassenmethoden werden häufig da eingesetzt, wo Funktionalitäten +zur Verfügung gestellt werden, die nicht datenzentriert arbeiten +oder auf primitiven Datentypen operieren. Beispiele für beide +Arten sind in der Klassenbibliothek zu finden. Zur ersten Gruppe gehören +beispielsweise die Methoden der Klasse System. +Die Klasse System +ist eine Art Toolbox, die Funktionen wie Aufruf des Garbage Collectors +oder Beenden des Programms zur Verfügung stellt. Zur zweiten +Gruppe gehören beispielsweise die Methoden der Klasse Math, +die eine große Anzahl an Funktionen zur Fließkomma-Arithmetik +zur Verfügung stellen. Da die Fließkommatypen primitiv +sind, hätte ein instanzbasiertes Methodendesign an dieser Stelle +wenig Sinn. + +

+Eine weitere Anwendung für Klassenmethoden liegt in der Instanzierung +von Objekten der eigenen Klasse. Beispiele dafür finden sich +in den Design-Patterns Singleton (siehe Abschnitt 10.4.1) +und Factory-Methode (siehe Abschnitt 10.4.4).

+ + + + +
 Tipp 
+
+ +

+Das folgende Listing zeigt die Verwendung der Klassenmethode sqrt +der Klasse Math +zur Ausgabe einer Tabelle von Quadratwurzeln: + + +

+ + + + + +
+ +
+001 /* Listing0809.java */
+002 
+003 public class Listing0809
+004 {
+005   public static void main(String[] args)
+006   {
+007     double x, y;
+008     for (x = 0.0; x <= 10.0; x = x + 1.0) {
+009       y = Math.sqrt(x);
+010       System.out.println("sqrt("+x+") = "+y);
+011     }
+012   }
+013 }
+
+
+Listing0809.java
+ +Listing 8.9: Verwendung von Math.sqrt

+ +

+Die Ausgabe des Programms ist: + +

+sqrt(0.0) = 0.0
+sqrt(1.0) = 1.0
+sqrt(2.0) = 1.4142135623730951
+sqrt(3.0) = 1.7320508075688772
+sqrt(4.0) = 2.0
+sqrt(5.0) = 2.23606797749979
+sqrt(6.0) = 2.449489742783178
+sqrt(7.0) = 2.6457513110645907
+sqrt(8.0) = 2.8284271247461903
+sqrt(9.0) = 3.0
+sqrt(10.0) = 3.1622776601683795
+
+ + + + + +

Die statische Methode main

+ +

+Ein schon bekanntes Beispiel für eine Klassenmethode ist die +Methode main, +die als Startpunkt in Applikationen verwendet wird. Im Gegensatz zu +Applets, bei denen vom Laufzeitsystem eine Instanz der Appletklasse +erzeugt und dann durch Aufruf von Callback-Methoden bedient wird, +erfolgt der Start einer Applikation ohne die Instanzierung einer Klasse. +Der Java-Interpreter lädt lediglich das beim Starten angegebene +Klassenobjekt und sucht nach einer statischen Methode mit der Signatur: + +

+public static void main(String[] args)
+
+ + +

+Wird diese gefunden, stellt es ein Array mit den Kommandozeilenparametern +zusammen und übergibt es als Argument an main. +Wird keine Methode mit dieser Signatur gefunden, gibt es einen Laufzeitfehler. + + + + +

8.3.4 Statische Initialisierer

+ +

+Bisher haben wir nur die Möglichkeit kennengelernt, statischen +Variablen während der Deklaration einen Wert zuzuweisen. Falls +komplexere Initialisierungen benötigt werden, können zur +Initialisierung von statischen Variablen statische Initialisierer +definiert werden. + +

+Sie ähneln gewöhnlichen Konstruktoren und dienen wie diese +dazu, Variablen mit einem definierten Startwert zu belegen. Im Gegensatz +zu einem gewöhnlichen Konstruktor erfolgt der Aufruf eines statischen +Initialisierers aber nicht mit jedem neu angelegten Objekt, sondern +nur einmal, wenn die Klasse geladen wird. + +

+Ein statischer Initialisierer wird als parameterlose Methode mit dem +Namen static +definiert: + + +

+ + + + +
+ +
+001 class Test
+002 {
+003   static int i;
+004   static int j;
+005 
+006   static
+007   {
+008     i = 5;
+009     j = 3 * i;
+010   }
+011 }
+
+
+ +Listing 8.10: Definition eines statischen Initialisierers

+ +

+Da der statische Initialisierer vom Laufzeitsystem aufgerufen wird, +wenn die Klasse geladen wird, ist eine benutzerdefinierte Parametrisierung +nicht möglich. +

+ + + + + + + + + +
+ +

+Es ist erlaubt, mehrere statische Initialisierer innerhalb einer Klasse +zu definieren. Sie werden dann nacheinander in der textuellen Reihenfolge +ihrer Deklaration ausgeführt. Wechseln sich initialisierte statische +Variablen und statische Initialisierer im Quelltext ab, werden beide +gleichwertig behandelt, d.h. die Ausführung erfolgt unabhängig +vom Typ in textueller Reihenfolge. Eine Ausnahme bilden lediglich +die statischen Variablen, denen Konstanten zugewiesen werden, deren +Wert bereits zur Compile-Zeit feststeht. Ihre Initialisierung erfolgt +- unabhängig von ihrer Position im Quellcode - unmittelbar nach +dem Laden der Klasse.

+ + + + +
 Hinweis 
+
+


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3