Rheinwerk Computing < openbook >


 
Inhaltsverzeichnis
Materialien
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Arrays und ihre Anwendungen
5 Der Umgang mit Zeichenketten
6 Eigene Klassen schreiben
7 Objektorientierte Beziehungsfragen
8 Ausnahmen müssen sein
9 Geschachtelte Typen
10 Besondere Typen der Java SE
11 Generics<T>
12 Lambda-Ausdrücke und funktionale Programmierung
13 Architektur, Design und angewandte Objektorientierung
14 Java Platform Module System
15 Die Klassenbibliothek
16 Einführung in die nebenläufige Programmierung
17 Einführung in Datenstrukturen und Algorithmen
18 Einführung in grafische Oberflächen
19 Einführung in Dateien und Datenströme
20 Einführung ins Datenbankmanagement mit JDBC
21 Bits und Bytes, Mathematisches und Geld
22 Testen mit JUnit
23 Die Werkzeuge des JDK
A Java SE-Module und Paketübersicht
Stichwortverzeichnis


Download:

- Listings, ca. 2,7 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil6 Eigene Klassen schreiben
Pfeil6.1 Eigene Klassen mit Eigenschaften deklarieren
Pfeil6.1.1 Attribute deklarieren
Pfeil6.1.2 Methoden deklarieren
Pfeil6.1.3 Verdeckte (shadowed) Variablen
Pfeil6.1.4 Die this-Referenz
Pfeil6.2 Privatsphäre und Sichtbarkeit
Pfeil6.2.1 Für die Öffentlichkeit: public
Pfeil6.2.2 Kein Public Viewing – Passwörter sind privat
Pfeil6.2.3 Wieso nicht freie Methoden und Variablen für alle?
Pfeil6.2.4 Privat ist nicht ganz privat: Es kommt darauf an, wer’s sieht *
Pfeil6.2.5 Zugriffsmethoden für Attribute deklarieren
Pfeil6.2.6 Setter und Getter nach der JavaBeans-Spezifikation
Pfeil6.2.7 Paketsichtbar
Pfeil6.2.8 Zusammenfassung zur Sichtbarkeit
Pfeil6.3 Eine für alle – statische Methoden und statische Attribute
Pfeil6.3.1 Warum statische Eigenschaften sinnvoll sind
Pfeil6.3.2 Statische Eigenschaften mit static
Pfeil6.3.3 Statische Eigenschaften über Referenzen nutzen? *
Pfeil6.3.4 Warum die Groß- und Kleinschreibung wichtig ist *
Pfeil6.3.5 Statische Variablen zum Datenaustausch *
Pfeil6.3.6 Statische Eigenschaften und Objekteigenschaften *
Pfeil6.4 Konstanten und Aufzählungen
Pfeil6.4.1 Konstanten über statische finale Variablen
Pfeil6.4.2 Typunsichere Aufzählungen
Pfeil6.4.3 Aufzählungstypen: typsichere Aufzählungen mit enum
Pfeil6.5 Objekte anlegen und zerstören
Pfeil6.5.1 Konstruktoren schreiben
Pfeil6.5.2 Verwandtschaft von Methode und Konstruktor
Pfeil6.5.3 Der Standard-Konstruktor (default constructor)
Pfeil6.5.4 Parametrisierte und überladene Konstruktoren
Pfeil6.5.5 Copy-Konstruktor
Pfeil6.5.6 Einen anderen Konstruktor der gleichen Klasse mit this(…) aufrufen
Pfeil6.5.7 Immutable-Objekte und Wither-Methoden
Pfeil6.5.8 Ihr fehlt uns nicht – der Garbage-Collector
Pfeil6.6 Klassen- und Objektinitialisierung *
Pfeil6.6.1 Initialisierung von Objektvariablen
Pfeil6.6.2 Statische Blöcke als Klasseninitialisierer
Pfeil6.6.3 Initialisierung von Klassenvariablen
Pfeil6.6.4 Eincompilierte Belegungen der Klassenvariablen
Pfeil6.6.5 Exemplarinitialisierer (Instanzinitialisierer)
Pfeil6.6.6 Finale Werte im Konstruktor und in statischen Blöcken setzen
Pfeil6.7 Zum Weiterlesen
 

Zum Seitenanfang

6.3    Eine für alle – statische Methoden und statische Attribute Zur vorigen ÜberschriftZur nächsten Überschrift

Exemplarvariablen sind eng mit ihrem Objekt verbunden. Wird ein Objekt geschaffen, erhält es einen eigenen Satz von Exemplarvariablen, die zusammen den Zustand des Objekts repräsentieren. Ändert eine Objektmethode den Wert einer Exemplarvariablen in einem Objekt, so hat dies keine Auswirkungen auf die Daten der anderen Objekte; jedes Objekt speichert eine individuelle Belegung. Es gibt jedoch auch Situationen, in denen Eigenschaften oder Methoden nicht direkt einem individuellen Objekt zugeordnet werden, sondern mit der Klasse, dem »Bauplan« der Objekte.

Diese Art von Zugehörigkeit unterstützt Java durch statische Eigenschaften. Da sie zu keinem Objekt gehören (wie Objekteigenschaften), nennen wir sie auch Klasseneigenschaften. Es gibt statische Methoden und statische Variablen – ein paar sind uns schon über den Weg gelaufen.

Statische Methoden

Statische Variablen

Math.random() liefert eine Zufallszahl.

System.out referenziert einen Ausgabestrom für die Standard-Konsolenausgabe.

Math.sin(…) berechnet den Sinus.

Math.PI bestimmt die Zahl 3,1415…

Integer.parseInt(…) konvertiert einen String in eine Ganzzahl.

Integer.MAX_VALUE ist die größte darstellbare int-Ganzzahl.

JOptionPane.showInputDialog(…) zeigt einen Eingabedialog.

Font.MONOSPACED steht für eine Schriftart fester Breite.

Color.HSBtoRGB(…)* konvertiert Farben vom HSB-Farbraum in den RGB-Farbraum.

MediaSize.ISO.A4 definiert die Größe einer DIN-A4-Seite, nämlich 210 mm × 297 mm.

* Ja, die Methode beginnt unüblicherweise mit einem Großbuchstaben.

Tabelle 6.4    Beispiele für statische Methoden und statische Variablen

Diese genannten Eigenschaften sind keinem konkreten Objekt zugeordnet, sondern vielmehr der Klasse. Die Sinus-Methode ist ein Beispiel für eine statische Methode der Math-Klasse, und MAX_VALUE ist ein statisches Attribut der Klasse Integer und out ein statisches Attribut der Klasse System. Alle diese Eigenschaften sind nicht an ein individuelles Objekt gebunden, sondern sozusagen »objektübergreifend«.

 

Zum Seitenanfang

6.3.1    Warum statische Eigenschaften sinnvoll sind Zur vorigen ÜberschriftZur nächsten Überschrift

Statische Eigenschaften haben gegenüber Objekteigenschaften den Vorteil, dass sie im Programm ausdrücken, keinen Zustand vom Objekt zu nutzen. Betrachten wir noch einmal die statischen Methoden aus der Klasse Math. Wenn sie Objektmethoden wären, so würden sie in der Regel mit einem Objektzustand arbeiten. Die statischen Methoden hätten keine Parameter und nähmen ihre Arbeitswerte nicht aus den Argumenten, sondern aus dem internen Zustand des Objekts. Das macht aber keine Math-Methode. Um den Sinus eines Winkels zu berechnen, benötigen wir kein spezifisches Mathe-Objekt. Andersherum könnte eine Methode wie setName(String) eines Spielers nicht statisch sein, da der Name ganz individuell für einen Spieler gesetzt werden soll und nicht alle Spieler-Objekte immer den gleichen Namen tragen sollten.

Statische Methoden sind aus diesem Grund häufiger als statische Variablen, da sie ihre Arbeitswerte ausschließlich aus den Parametern ziehen. Statische Variablen werden in erster Linie als Konstanten verwendet.

 

Zum Seitenanfang

6.3.2    Statische Eigenschaften mit static Zur vorigen ÜberschriftZur nächsten Überschrift

Um statische Eigenschaften in Java umzusetzen, fügen wir vor der Deklaration einer Variablen oder einer Methode das Schlüsselwort static hinzu. Für den Zugriff verwenden wir statt der Referenzvariablen einfach den Klassennamen.

  • Deklarieren wir eine statische Methode und eine statische Variable für eine Klasse GameUtils. Die Methode soll testen, ob Bezeichner, die im Spiel etwa für die Gegenstände verwendet werden, korrekt sind; ein korrekter Bezeichner ist nicht zu lang und enthält kein Sonderzeichen. Zum Testen greifen wir auf matches("\\w+") zurück, eine String-Methode, die mit einem regulären Ausdruck prüft, ob der gesamte String nur Wortzeichen[ 149 ](Laut https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/regex/Pattern.html ist \w gleichwertig zu [a-zA-Z_0-9], enthält also zum Beispiel deutsche Umlaute nicht. ) enthält.

  • Die Konstante MAX_ID_LEN steht für die maximale Bezeichnerlänge. Die Variable ist mit dem Modifizierer final versehen, da MAX_ID_LEN eine Konstante ist, deren Wert später nicht mehr verändert werden soll:

Listing 6.22    src/main/java/com/tutego/insel/oop/GameUtils.java

public class GameUtils {



public static final int MAX_ID_LEN = 20 /* chars */;



public static boolean isGameIdentifier( String name ) {

if ( name == null )

return false;



return name.length() <= MAX_ID_LEN && name.matches( "\\w+" );

}

}
Statische Eigenschaften werden in der UML unterstrichen.

Abbildung 6.9    Statische Eigenschaften werden in der UML unterstrichen.

Die statischen Eigenschaften werden mit dem Klassennamen GameUtils angesprochen:

Listing 6.23    src/main/java/com/tutego/insel/oop/GameUtilsDemo.java, main(), Ausschnitt

System.out.println( GameUtils.isGameIdentifier( "Superpig" ) );    // true

System.out.println( GameUtils.isGameIdentifier( "Superpig II" ) ); // false

inline image  Eclipse stellt statische Eigenschaften kursiv dar.

[+]  Tipp

Falls eine Klasse nur statische Eigenschaften deklariert, spricht nichts dagegen, einen privaten Konstruktor anzugeben – das verhindert den äußeren Aufbau von Objekten. Abschnitt 6.5.1, »Konstruktoren schreiben«, erklärt Konstruktoren genauer und erläutert auch weitere Anwendungsfälle für private Konstruktoren.

Gültigkeitsbereich, Sichtbarkeit und Lebensdauer

Bei statischen und nichtstatischen Variablen können wir deutliche Unterschiede in der Lebensdauer festmachen. Eine Objektvariable beginnt ihr Leben mit dem new, und sie endet mit der automatischen Speicherbereinigung, dem Garbage-Collector. Eine statische Variable dagegen beginnt ihr Leben in dem Moment, in dem die Laufzeitumgebung die Klasse lädt und initialisiert. Das Leben der statischen Variablen endet, wenn die JVM die Klasse entfernt und aufräumt. Der Zugriff auf statische Variablen ist immer in allen Blöcken gestattet, da ja auch in Objektmethoden die statische Variable »schon eher da war« als das Objekt selbst, denn ein new setzt ja die geladene Klassendefinition, die die statischen Variablen vorbereitet, voraus. Durch statische Variablen können schnell Speicherprobleme entstehen, wenn Entwickler vergesssen, dass sie große Objektbäume referenzieren. Und die bleiben so lange im Speicher wie die Klasse selbst – das kann bis zum Ende der Anwendung sein.

 

Zum Seitenanfang

6.3.3    Statische Eigenschaften über Referenzen nutzen? * Zur vorigen ÜberschriftZur nächsten Überschrift

Besitzt eine Klasse eine Klasseneigenschaft, so kann sie auch wie ein Objektattribut über die Referenz angesprochen werden. Dies bedeutet, dass es prinzipiell zwei Möglichkeiten gibt, wenn ein Objektexemplar existiert und die Klasse ein statisches Attribut hat. Bleiben wir bei unserem obigen Beispiel mit der Klasse GameUtils. Wir können für den Zugriff auf MAX_ID_LEN Folgendes schreiben:

System.out.println( GameUtils.MAX_ID_LEN );           // Genau richtig

GameUtils ut = new GameUtils();

System.out.println( ut.MAX_ID_LEN ); // Nicht gut

Zugriffe auf statische Eigenschaften sollten wir nie über die Objektreferenz schreiben, denn dem Leser ist sonst nicht klar, ob die Eigenschaft statisch oder nichtstatisch ist. Das zu wissen ist aber wichtig. Aus diesem Grund sollten wir statische Eigenschaften immer über ihren Klassennamen ansprechen.

inline image  Eclipse gibt eine Meldung aus, wenn statische Eigenschaften über eine Referenz verwendet werden, und bietet ein Refactoring an.

[»]  Hinweis

Bei statischen Zugriffen spielt die Referenz keine Rolle, und sie kann auch null sein. Wer im Wettbewerb um das schlechteste Java-Programm weit vorn sein möchte, der schreibt:

System.out.println( ((GameUtils) null).MAX_ID_LEN );
 

Zum Seitenanfang

6.3.4    Warum die Groß- und Kleinschreibung wichtig ist * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Vorgabe der Namenskonvention besagt: Klassennamen sind mit Großbuchstaben zu vergeben und Variablen-/Methodennamen mit Kleinbuchstaben (sofern die Variable keine Konstante beschreibt). Treffen wir auf eine Anweisung wie Math.random(), so wissen wir sofort, dass random() eine statische Methode sein muss, weil davor ein Bezeichner steht, der großgeschrieben ist. Dieser kennzeichnet also keine Referenz, sondern einen Klassennamen. Daher sollten wir in unseren Programmen großgeschriebene Objektnamen meiden.

Das folgende Beispiel demonstriert anschaulich, warum Referenzvariablen mit Kleinbuchstaben und Klassennamen mit Großbuchstaben beginnen sollten:

String StringModifier = "What is the Matrix?";

String t = StringModifier.trim();

Die trim()-Methode ist nicht statisch, wie die Anweisung durch die Großschreibung der Variablen suggeriert.

Das gleiche Problem haben wir, wenn wir Klassen mit Kleinbuchstaben benennen. Auch dies kann irritieren:

class player {

static void move() { }

}

Jetzt könnte jemand player.move() schreiben, und der Leser nähme an, dass player wegen seiner Kleinschreibung eine Referenzvariable wäre und move() eine Objektmethode. Wir sehen an diesem Beispiel, dass es wichtig ist, sich an die Groß-/Kleinschreibung zu halten.

 

Zum Seitenanfang

6.3.5    Statische Variablen zum Datenaustausch * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Belegung einer statischen Variablen wird bei dem Klassenobjekt gespeichert und nicht bei einem Exemplar der Klasse. Wie wir aber gesehen haben, kann jedes Exemplar einer Klasse auch auf die statischen Variablen der Klasse zugreifen. Da eine statische Variable aber nur einmal pro Klasse vorliegt, führt dies dazu, dass mehrere Objekte sich eine Variable teilen.

Ist etwa ein Attribut PI statisch und size ein Objektattribut, so ergibt sich bei zwei Exemplaren folgendes Bild:

Zwei Exemplare teilen sich das statische Attribut PI.

Abbildung 6.10    Zwei Exemplare teilen sich das statische Attribut PI.

Während also beide Exemplare das gleiche PI nutzen, können beide Exemplare size völlig unterschiedlich belegen.

Aufgebaute Exemplare mitzählen

Mit diesem Wissen wird es möglich, einen Austausch von Informationen über die Objektgrenze hinaus zu erlauben. Wir wollen das in einem Beispiel nutzen, in dem der Konstruktor die Anzahl der erzeugten Objekte mitzählt; eine statische Methode liefert später die bis dahin gebauten Exemplare:

Listing 6.24    src/main/java/com/tutego/insel/oop/Rollercoaster.java

public class Rollercoaster {



private static int numberOfInstances;



{

numberOfInstances++;

}



public static int getNumberOfInstances() {

return numberOfInstances;

}



public static void main( String[] args ) {

new Rollercoaster();

new Rollercoaster();



System.out.println( Rollercoaster.getNumberOfInstances() ); // 2

}

}

Die statische Variable numberOfInstances wird bei jedem neuen Exemplar über den Konstruktor hochgesetzt. Direkt ausgeschrieben ist der Konstruktor nicht, sondern es findet ein Exemplarinitialisierer Anwendung (siehe dazu Abschnitt 6.6.1, »Initialisierung von Objektvariablen«), da der Compiler den Code automatisch in jeden Konstruktor kopiert. Das hat den Vorteil, dass Entwickler später problemlos neue Konstruktoren für den Rollercoaster hinzufügen können, ohne das Inkrement der statischen Variablen immer im Hinterkopf behalten zu müssen.

[»]  Hinweis

Bei nebenläufigen Zugriffen auf statische Variablen kann es zu Problemen kommen. Deshalb müssen wir spezielle Synchronisationsmechanismen nutzen – die das Beispiel allerdings nicht verwendet. Statische Variablen können auch schnell zu Speicherproblemen führen, da Objektreferenzen sehr lange gehalten werden. Der Einsatz muss wohldurchdacht sein.

 

Zum Seitenanfang

6.3.6    Statische Eigenschaften und Objekteigenschaften * Zur vorigen ÜberschriftZur nächsten Überschrift

Wie wir oben gesehen haben, können wir über eine Objektreferenz auch statische Eigenschaften nutzen. Wir wollen uns aber noch einmal vergewissern, wie Objekteigenschaften und statische Eigenschaften gemischt werden können. Erinnern wir uns daran, dass unsere ersten Programme aus der statischen main(…)-Methode bestanden, aber unsere anderen Methoden auch static sein mussten. Dies ist sinnvoll, da eine statische Methode – ohne explizite Angabe eines aufrufenden Objekts – nur andere statische Methoden aufrufen kann. Wie sollte auch eine statische Methode eine Objektmethode aufrufen können, wenn es kein zugehöriges Objekt gibt? Andersherum kann aber jede Objektmethode eine beliebige statische Methode direkt aufrufen. Genauso verhält es sich mit Attributen. Eine statische Methode kann keine Objektattribute nutzen, da es kein implizites Objekt gibt, auf dessen Eigenschaften zugegriffen werden könnte.

this-Referenzen und statische Eigenschaften

Auch der Einsatz der this-Referenz ist bei statischen Eigenschaften nicht möglich. Eine statische Methode kann also keine this-Referenz verwenden; auf welches Objekt sollte this auch zeigen?

Listing 6.25    src/main/java/com/tutego/insel/oop/InStaticNoThis.java, Ausschnitt

class InStaticNoThis {



String name;



void printName() {

System.out.println( name );

}



public static void main( String[] args ) {

name = "Amanda"; // inline image Cannot make a static reference to the non-static field name

printName(); // inline image Cannot make a static reference to the non-static method

// printName() from the type InStaticNoThis

System.out.println( this ); // inline image Cannot use this in a static context

}

}

Auch im statischen Initialisierungsblock (siehe dazu Abschnitt 6.6.2, »Statische Blöcke als Klasseninitialisierer«) ist this nicht erlaubt.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Objektorientierte Programmierung

Objektorientierte Programmierung




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2021

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.

Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de



Cookie-Einstellungen ändern