Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Die Klassenbibliothek
14 Einführung in die nebenläufige Programmierung
15 Einführung in Datenstrukturen und Algorithmen
16 Einführung in grafische Oberflächen
17 Einführung in Dateien und Datenströme
18 Einführung ins Datenbankmanagement mit JDBC
19 Einführung in <XML>
20 Testen mit JUnit
21 Bits und Bytes und Mathematisches
22 Die Werkzeuge des JDK
A Java SE Paketübersicht
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 20,0 MB
- Übungsaufgaben, ca. 1,8 MB
- Musterlösungen, ca. 0,8 MB

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenbloom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Rheinwerk Computing
1306 Seiten, gebunden, 11. Auflage
49,90 Euro, ISBN 978-3-8362-2873-2
Pfeil 9 Besondere Typen der Java SE
Pfeil 9.1 Vergleichen von Objekten
Pfeil 9.1.1 Natürlich geordnet oder nicht?
Pfeil 9.1.2 Die Schnittstelle Comparable
Pfeil 9.1.3 Die Schnittstelle Comparator
Pfeil 9.1.4 Rückgabewerte kodieren die Ordnung
Pfeil 9.1.5 Statische und Default-Methoden in Comparator
Pfeil 9.2 Wrapper-Klassen und Autoboxing
Pfeil 9.2.1 Wrapper-Objekte erzeugen
Pfeil 9.2.2 Konvertierungen in eine String-Repräsentation
Pfeil 9.2.3 Von einer String-Repräsentation parsen
Pfeil 9.2.4 Die Basisklasse Number für numerische Wrapper-Objekte
Pfeil 9.2.5 Vergleiche durchführen mit compare(…), compareTo(…), equals(…) und Hashwerten
Pfeil 9.2.6 Statische Reduzierungsmethoden in Wrapper-Klassen
Pfeil 9.2.7 Die Größe eines primitiven Typs in den Wrapper-Konstanten SIZE und BYTES
Pfeil 9.2.8 Behandeln von vorzeichenlosen Zahlen *
Pfeil 9.2.9 Die Klasse Integer
Pfeil 9.2.10 Die Klassen Double und Float für Fließkommazahlen
Pfeil 9.2.11 Die Long-Klasse
Pfeil 9.2.12 Die Boolean-Klasse
Pfeil 9.2.13 Autoboxing: Boxing und Unboxing
Pfeil 9.3 Object ist die Mutter aller Klassen
Pfeil 9.3.1 Klassenobjekte
Pfeil 9.3.2 Objektidentifikation mit toString()
Pfeil 9.3.3 Objektgleichheit mit equals(…) und Identität
Pfeil 9.3.4 Klonen eines Objekts mit clone() *
Pfeil 9.3.5 Hashwerte über hashCode() liefern *
Pfeil 9.3.6 System.identityHashCode(…) und das Problem der nicht eindeutigen Objektverweise *
Pfeil 9.3.7 Aufräumen mit finalize() *
Pfeil 9.3.8 Synchronisation *
Pfeil 9.4 Die Utility-Klasse java.util.Objects
Pfeil 9.5 Iterator, Iterable *
Pfeil 9.5.1 Die Schnittstelle Iterator
Pfeil 9.5.2 Wer den Iterator liefert
Pfeil 9.5.3 Die Schnittstelle Iterable
Pfeil 9.5.4 Erweitertes for und Iterable
Pfeil 9.5.5 Interne Iteration (seit Java 8)
Pfeil 9.5.6 Einen eigenen Iterable implementieren *
Pfeil 9.6 Die Spezial-Oberklasse Enum
Pfeil 9.6.1 Methoden auf Enum-Objekten
Pfeil 9.6.2 Aufzählungen mit eigenen Methoden *
Pfeil 9.6.3 enum mit eigenen Konstruktoren *
Pfeil 9.7 Zum Weiterlesen
 
Zum Seitenanfang

9.6Die Spezial-Oberklasse Enum Zur vorigen ÜberschriftZur nächsten Überschrift

Jeder Aufzählungstyp erbt von der Spezialklasse Enum. Nehmen wir erneut die Wochentage:

Listing 9.34com/tutego/insel/enumeration/Weekday.java, Weekday

public enum Weekday {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

Der Compiler übersetzt dies in eine Klasse, die etwa so aussieht:

class Weekday extends Enum {

public static final Weekday MONDAY = new Weekday( "MONDAY", 0 );
public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
// weitere Konstanten ...

private Weekday( String s, int i ) {
super( s, i );
}

// weitere Methoden ...
}
 
Zum Seitenanfang

9.6.1Methoden auf Enum-Objekten Zur vorigen ÜberschriftZur nächsten Überschrift

Jedes Enum-Objekt besitzt automatisch einige Standardmethoden, die von der Oberklasse java.lang.Enum kommen. Das sind zum einen überschriebene Methoden aus java.lang.Object, einige neue Objektmethoden und einige statische Methoden.

Typbeziehung von Enum

Abbildung 9.7Typbeziehung von Enum

String-Repräsentation

Über die Methode name() liefert ein Enum-Objekt den Namen der Konstante. Dazu gesellt sich die bekannte toString()-Methode, die standardmäßig name() aufruft, aber überschrieben werden kann. Die Methode name() lässt sich nicht überschreiben.

Eine vom Compiler generierte Enum-Klasse bietet eine statische valueOf(String)-Methode, die das Enum-Objekt liefert, das zur name()-Repräsentation passt. Wird bei valueOf(String) ein String übergeben, zu dem es kein Enum gibt, folgt eine IllegalArgumentException. Dazu kommt eine weitere statische Methode, die jedoch selbst schon in der Klasse Enum deklariert wird (die Basisklasse der vom Compiler erzeugten Enum-Klassen): Enum.valueOf(Class<T> enumType, String s).

[zB]Beispiel

Die Konvertierung in den String und vom String in das entsprechende Enum-Objekt:

System.out.println( Weekday.MONDAY.toString() ); // MONDAY
System.out.println( Weekday.MONDAY.name() ); // MONDAY
System.out.println( Weekday.valueOf( "MONDAY" ).name() ); // MONDAY
System.out.println( Enum.valueOf( Weekday.class, "MONDAY" ).name() ); // MONDAY

Der Unterschied zu den valueOf(…)-Methoden ist wichtig: Während es Enum.valueOf(Class, String) nur einmal gibt, existieren statische valueOf(String)-Methoden einmal in jeder vom Compiler generierten Aufzählungsklasse. Da die Methode also compilergeneriert ist, taucht sie in der folgenden Aufzählung nicht auf:

abstract class java.lang.Enum<E extends Enum<E>>
implements Comparable<E>, Serializable

  • final String name()
    Liefert den Namen der Konstanten. Da die Methode – wie viele andere der Klasse – final ist, lässt sich der Name nicht ändern.

  • String toString()
    Liefert den Namen der Konstanten. Die Methode ruft standardisiert name() auf, weil sie aber nicht final ist, kann sie überschrieben werden.

  • static <T extends Enum<T>> T valueOf(Class<T> enumType, String s)
    Ermöglicht das Suchen von Enum-Objekten zu einem Konstantennamen und einer Enum-Klasse. Sie liefert das Enum-Objekt für die gegebene Zeichenfolge oder löst eine IllegalArgumentException aus, wenn dem String kein Enum-Objekt zuzuordnen ist.

Alle Konstanten der Klasse aufzählen

Eine praktische statische Methode ist values(). Sie liefert ein Feld von allen Aufzählungen vom Aufzählungstyp. Nützlich ist das für das erweiterte for, das alle Konstanten aufzählen soll. Eine Alternative mit dem gleichen Ergebnis ist die Class-Methode getEnumConstants():

Listing 9.35com/tutego/insel/enumeration/WeekdayDemo.java, Ausschnitt main()

for ( Weekday day : Weekday.values() ) // oder Weekday.class.getEnumConstants()
System.out.println( "Name=" + day.name() );

Liefert Zeilen mit Name=MONDAY, ...

Ordinalzahl

Von der Oberklasse Enum erbt jede Aufzählung einen geschützten parametrisierten Konstruktor, der den Namen der Konstanten sowie einen assoziierten Zähler erwartet. So wird aus jedem Element der Aufzählung ein Objekt vom Basistyp Enum, das einen Namen und eine ID, die so genannte Ordinalzahl, speichert. Natürlich kann es auch nach seinem Namen und Zähler gefragt werden.

[zB]Beispiel

Eine Methode, die die Ordinalzahl eines Elements der Aufzählung liefert oder –1, wenn die Konstante nicht existiert:

Listing 9.36com/tutego/insel/enumeration/WeekdayDemo.java, getOrdinal()

static int getOrdinal( String name ) {
try {
return Weekday.valueOf( name ).ordinal();
}
catch ( IllegalArgumentException e ) {
return –1;
}
}

Damit liefert unser getOrdinal("MONDAY") == 0 und getOrdinal("WOCHENTAG") == –1.

Die Ordinalzahl gibt die Position in der Deklaration an und ist auch Ordnungskriterium der compareTo(…)-Methode. Die Ordinalzahl lässt sich nicht ändern und repräsentiert immer die Reihenfolge der deklarieren Konstanten.

[zB]Beispiel

Kommt Montag wirklich vor Freitag?

System.out.println( Weekday.MONDAY.compareTo( Weekday.FRIDAY ) ); // –4
System.out.println( Weekday.MONDAY.compareTo( Weekday.MONDAY ) ); // 0
System.out.println( Weekday.FRIDAY.compareTo( Weekday.MONDAY) ); // 4

Negative Rückgaben bei compareTo(…) geben immer an, dass das erste Objekt »kleiner« als das zweite aus dem Argument ist.

abstract class java.lang.Enum<E extends Enum<E>>
implements Comparable<E>, Serializable

  • final int ordinal()
    Liefert die zur Konstante gehörige ID. Im Allgemeinen ist diese Ordinalzahl nicht wichtig, aber besondere Datenstrukturen wie EnumSet oder EnumMap nutzen diese eindeutige ID. Die Reihenfolge der Zahlen ist durch die Reihenfolge der Angabe gegeben.

  • public final boolean equals(Object other)
    Die Oberklasse Enum überschreibt equals(…) mit der Logik wie in Object – also den Vergleich der Referenzen –, um sie als final zu markieren.

  • protected final Object clone() throws CloneNotSupportedException
    Die Methode clone() ist final protected und kann also weder überschrieben noch von außen aufgerufen werden. So kann es keine Kopien der Enum-Objekte geben, die die Identität gefährden könnten. Grundsätzlich ist es aber erlaubt, wenn eigene Implementierungen von clone() die this-Referenz liefern.

  • final int compareTo(E o)
    Da die Enum-Klasse die Schnittstelle Comparable implementiert, gibt es auch die Methode compareTo(…). Sie vergleicht anhand der Ordinalzahlen. Vergleiche sind nur innerhalb eines Enum-Typs erlaubt.

  • final Class<E> getDeclaringClass()
    Liefert das Class-Objekt von der Aufzählungsklasse zu einem konkreten Enum. Achtung: Die Methode liefert, auf der Aufzählungsklasse selbst angewendet, null und nur auf den Elementen der Aufzählung einen sinnvollen Wert. So wäre Weekday.class.getDeclaringClass() gleich null, aber Weekday.MONDAY.getDeclaringClass() wie gewünscht com.tutego.weekday.Weekday.

[+]Hinweis

Vom Class-Objekt ist die Methode getEnumConstants() noch interessant, denn auch sie gibt wie values() ein Feld mit allen Einträgen zurück. Der Vorteil über das Class-Objekt ist jedoch, dass es generischer ist; der Aufruf der statischen values()-Methode ist immer mit der Klasse verbunden, getEnumConstants() funktioniert bei jedem Class-Objekt, und selbst wenn es keine Aufzählungsklasse repräsentieren sollte, ist die Rückgabe null.

 
Zum Seitenanfang

9.6.2Aufzählungen mit eigenen Methoden * Zur vorigen ÜberschriftZur nächsten Überschrift

Da ein enum-Typ eine besondere Form der Klassendeklaration ist, kann er ebenso Attribute und Methoden deklarieren. Jede Aufzählung hat ja schon Methoden wie name() und ordinal(), und da können Entwickler auch eigene hinzufügen.

Country mit zusätzlicher Objektmethode

Geben wir einer Aufzählung Country eine Methode, die den ISO-3166-2-Landescode des jeweiligen Aufzählungselements liefert:

Listing 9.37com/tutego/insel/enumeration/Country.java, Country

public enum Country {

GERMANY, UK, CHINA;

public String getISO3Country() {
if ( this == GERMANY )
return Locale.GERMANY.getISO3Country();
else if ( this == UK )
return Locale.UK.getISO3Country();
return Locale.CHINA.getISO3Country();
}
}

Die Methode getISO3Country() kann nun auf der Aufzählung aufgerufen werden:

System.out.println( Country.CHINA.getISO3Country() ); // CHN

Da switch auf Aufzählungen erlaubt ist, können wir Folgendes schreiben:

Listing 9.38com/tutego/insel/enumeration/CountryEnumDemo.java, Ausschnitt

Country c = Country.GERMANY;

switch ( c ) {
case GERMANY:
System.out.println( "Aha. Ein Krauti" ); // Aha. Ein Krauti
System.out.println( c.getISO3Country() ); // DEU
break;
default: System.out.println( "Anderes Land" );
}

Country mit zusätzlicher Klassenmethode

Auf Aufzählungstyp kann statische Methoden besitzen, aber natürlich dann nur auf statische Eigenschaften zugreifen, wie values() auf einzelne Aufzählungselemente.

[zB]Beispiel

Deklariere eine Aufzählung Country und zwei statischen Methoden, sodass Country.getDefault() GERMANY liefert und Country.random() ein Zufallsland:

public enum Country {
GERMANY, UK, CHINA;
public static Country getDefault() { return GERMANY; }
public static Country random() { return values()[ (int)(Math.random()*3 ) ]; }
}
 
Zum Seitenanfang

9.6.3enum mit eigenen Konstruktoren * Zur vorigen ÜberschriftZur nächsten Überschrift

Neben der ersten Variante für getISO3Country() wollen wir eine zweite Implementierung nutzen und nun Konstruktoren hinzuziehen, um das gleiche Problem auf andere Weise zu lösen:

Listing 9.39com/tutego/insel/enumeration/Country2.java, Country2

public enum Country2 {

GERMANY( Locale.GERMANY ),
UK( Locale.UK ),
CHINA( Locale.CHINA );

private Locale country;

private Country2( Locale country ) {
this.country = country;
}

public String getISO3Country()
{
return country.getISO3Country();
}
}

Bei der Deklaration der Konstanten wird in runden Klammern ein Argument für den Konstruktor übergeben. Der Konstruktor speichert das zugehörige Locale-Objekt in der internen Variablen country, auf die dann getISO3Country() Bezug nimmt.

enum mit überschriebenen Methoden

In dem Aufzählungstyp lassen sich nicht nur Methoden hinzufügen, sondern auch Methoden überschreiben. Beginnen wir mit einer lokalisierten und überladenen Methode toString():

Listing 9.40com/tutego/insel/enumeration/WeekdayInternational.java, WeekdayInternational

public enum WeekdayInternational {

SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

@Override
public String toString() {
return toString( Locale.getDefault() );
}

public String toString( Locale l ) {
return new SimpleDateFormat( "", l ).getDateFormatSymbols()
.getWeekdays()[ ordinal() + 1 ];
}
}

Die erste Methode ist aus unserer Oberklasse Object überschrieben, die zweite als überladene Methode hinzugefügt. Ein Beispiel macht den Aufruf und die Funktionsweise klar:

Listing 9.41com/tutego/insel/enumeration/WeekdayInternationalDemo.java, main()

System.out.println( WeekdayInternational.SATURDAY );
// Samstag
System.out.println( WeekdayInternational.SATURDAY.toString() );
// Samstag
System.out.println( WeekdayInternational.SATURDAY.toString(Locale.FRANCE) );
// samedi
System.out.println( WeekdayInternational.SATURDAY.toString(Locale.ITALY) );
// sabato

An dieser Stelle hören die Möglichkeiten der enum-Syntax aber noch nicht auf. Ähnlich wie die Syntax von inneren anonymen Klassen, die es erlauben, Methoden zu überschreiben, bieten Aufzählungstypen eine vergleichbare Syntax, um gezielt Methoden für eine spezielle Konstante zu überschreiben.

Nehmen wir an, in einem Spiel gibt es eine eigene Währung, den Ponro-Dollar. Nun soll dieser aber zu einer Referenzwährung, dem Euro, in Beziehung gesetzt werden; der Wechselkurs ist einfach 1 : 2:

Listing 9.42com/tutego/insel/enumeration/GameCurrency.java, GameCurrency

public enum GameCurrency {

EURO() {
@Override double convertTo( GameCurrency targetCurrency, double value ) {
return targetCurrency == EURO ? value : value / 2;
}
},
PONRODOLLAR() {
@Override double convertTo( GameCurrency targetCurrency, double value ) {
return targetCurrency == PONRODOLLAR ? value : value * 2;
}
};

abstract double convertTo( GameCurrency targetCurrency, double value );
}

Der interessante Teil ist die Deklaration der abstrakten convertTo(…)-Methode und die Implementierung lokal bei den einzelnen Konstanten. (Natürlich müssen wir nicht jede Methode im enum abstrakt machen, sondern sie kann auch konkret sein. Dann muss nicht jedes enum-Element die abstrakte Methode implementieren.)

Mit einem statischen Import für die Aufzählung lässt sich die Nutzung und Funktionalität schnell zeigen:

Listing 9.43com/tutego/insel/enumeration/GameCurrencyDemo.java, main()

System.out.println( EURO.convertTo( EURO, 12 ) ); // 12.0
System.out.println( EURO.convertTo( PONRODOLLAR, 12 ) ); // 6.0
System.out.println( PONRODOLLAR.convertTo( EURO, 12 ) ); // 24.0
System.out.println( PONRODOLLAR.convertTo( PONRODOLLAR, 12 ) ); // 12.0

enum kann Schnittstellen implementieren

Die API-Dokumentation von Enum zeigt an, dass die abstrakte Klasse zwei Schnittstellen implementiert: Comparable und Serializable. Jede in enum deklarierte Konstante ist Unterklasse von Enums, also immer vergleichbar und standardmäßig serialisierbar. Neben diesen Standardschnittstellen kann ein enum andere Schnittstellen implementieren. Das ist sehr nützlich, denn so schreibt es für alle Aufzählungselemente ein bestimmtes Verhalten vor – jedes Aufzählungselement bietet dann diese Operationen. Die Operationen der Schnittstelle können auf zwei Arten realisiert werden: Das enum selbst implementiert die Operationen der Schnittstelle im Rumpf, oder die einzelnen Aufzählungselemente realisieren die Implementierungen jeweils unterschiedlich. Oftmals dürfte es so sein, dass die Elemente unterschiedliche Implementierungen bereitstellen.

Unser nächstes kleines Beispiel für eine enum DefaultIcons implementiert die Schnittstelle Icon für grafische Symbole. Da die Symbole alle die gleichen Ausmaße haben, sind die Icon-Operationen getIconWidth() und getIconHeight() immer gleich und werden nur einmal implementiert; die tatsächlichen paintIcon(…)-Implementierungen (die hier nur angedeutet werden) unterscheiden sich.

Listing 9.44com/tutego/insel/enumeration/DefaultIcons.java, DefaultIcons

public enum DefaultIcons implements Icon {

WARNING {
@Override public void paintIcon( Component c, Graphics g, int x, int y ) {
// g.drawXXX()
} },
ERROR {
@Override public void paintIcon( Component c, Graphics g, int x, int y ) {
// g.drawXXX()
} };

@Override public int getIconWidth() { return 16; }

@Override public int getIconHeight() { return 16; }
}

Der Zugriff DefaultIcons.ERROR gibt ein Objekt, das unter anderem vom Typ Icon ist und an allen Stellen übergeben werden kann, an denen ein Icon gewünscht ist.

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel
Jetzt bestellen

 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java SE 8 Standard-Bibliothek
Java SE 8 Standard-Bibliothek


Zum Katalog: Professionell entwickeln mit Java EE 7
Professionell entwickeln mit Java EE 7


Zum Katalog: Schrödinger programmiert Java
Schrödinger programmiert Java


Zum Katalog: Einführung in Java
Einführung in Java


Zum Katalog: Programmieren lernen mit Java
Programmieren lernen mit Java


Zum Katalog: Apps entwickeln für Android 5
Apps entwickeln für Android 5


Zum Katalog: Apps entwickeln mit Android Studio
Apps entwickeln mit Android Studio


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2016
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.

 
Nutzungsbestimmungen | Datenschutz | Impressum

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