Wrapperklassen: Unterschied zwischen den Versionen
(Inhalt hinzugefügt) |
Keine Bearbeitungszusammenfassung |
||
| (3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 34: | Zeile 34: | ||
}} | }} | ||
{{Inhaltsblock | |||
|vorher=Primitive Datentypen können durch eine Zuweisung in Wrapperklassen ein- und ausgepackt (''auto-boxing'' und ''auto-unboxing'') werden: | |||
|Beispiel=Integer foo = 123; //auto-boxing | |||
int bar = foo; //auto-unboxing | |||
|nachher=Wie alle Referenzdatentypen können auch Instanzen von Wrapperklassen den Wert <syntaxhighlight inline lang="Java">null</syntaxhighlight> annehmen. Bei primitiven Datentypen ist das nicht möglich. Bei dem Versuch, eine <syntaxhighlight inline lang="Java">null</syntaxhighlight>-Referenz auszupacken, wird eine <syntaxhighlight inline lang="Java">NullPointerException</syntaxhighlight> geworfen. | |||
}} | |||
{{Inhaltsblock | |||
|vorher====Richtige Verwendung=== | |||
}} | |||
{{Inhaltsblock | |||
|vorher=*; Parsen | |||
Häufig liegen Werte von primitiven Datentypen als <syntaxhighlight inline lang="Java">String</syntaxhighlight> vor, z. B. nach Benutzereingaben. Damit diese sicher in den primitiven Datentyp umgewandelt werden können, stellt jede Wrapperklasse, außer <syntaxhighlight inline lang="Java">Character</syntaxhighlight>, eine statische <syntaxhighlight inline lang="Java">parse*()</syntaxhighlight> Methode zur Verfügung. Der ''*'' representiert dabei den primitiven Datentyp. | |||
}} | |||
{{Inhaltsblock | |||
|color=red | |||
|vorher=====Negativbeispiel==== | |||
Das folgende Programm versucht <syntaxhighlight inline lang="Java">"123"</syntaxhighlight> in einen <syntaxhighlight inline lang="Java">int</syntaxhighlight> zu überführen. | |||
|Beispiel=char[] characters = "123".toCharArray(); | |||
int number = 0; | |||
for (char character : characters) { | |||
number = number * 10 + (character - '0'); | |||
} | |||
System.out.println(number); | |||
|nachher=Die Lösung ist ineffizient, ignoriert einen möglichen Integer-Überlauf und berechnet einen falschen Wert, wenn <syntaxhighlight inline lang="Java">character</syntaxhighlight> keine Zahl zwischen 0-9 ist. Sie sollte daher auf keinen Fall verwendet werden. | |||
}} | |||
{{Inhaltsblock | |||
|color=green | |||
|vorher=====Positivbeispiel==== | |||
|Beispiel=int number = 0; | |||
try { | |||
number = Integer.parseInt("123"); | |||
} catch (NumberFormatException e) { | |||
System.out.println("Error, " + e.getMessage()); | |||
} | |||
System.out.println(number); | |||
|nachher=Dieser Ansatz verwendet die bereitgestellte <syntaxhighlight inline lang="Java">Integer.parseInt()</syntaxhighlight>-Methode, die intern bereits alle möglichen Fehler abdeckt. Außerdem ist diese Lösung deutlich verständlicher. Die Ausnahme <syntaxhighlight inline lang="Java">NumberFormatException</syntaxhighlight> sollte immer abgefangen werden, mehr dazu [[Runtime_Exceptions|hier]]. | |||
}} | |||
{{Inhaltsblock | |||
|vorher=*; Primitive Datentypen vor Wrapperklassen | |||
}} | |||
{{Inhaltsblock | |||
|color=red | |||
|vorher=====Negativbeispiel==== | |||
|Beispiel=Integer[] values = new Integer[] { 1, 2, 3, 4 }; | |||
Integer sum = 0; | |||
for (Integer value : values) { | |||
sum += value; | |||
} | |||
System.out.println(sum); | |||
|nachher=Da das Array nur Ganzzahlen enthält ist es hier unnötig, die Wrapperklasse <syntaxhighlight inline lang="Java">Integer</syntaxhighlight> zu verwenden. Das selbe Ergebnis kann auch mit dem primitiven <syntaxhighlight inline lang="Java">int</syntaxhighlight> erzielt werden. Gleiches gilt auch für einfache Variablen | |||
}} | |||
{{Inhaltsblock | |||
|color=green | |||
|vorher=====Positivbeispiel==== | |||
|Beispiel=int[] values = new int[] { 1, 2, 3, 4 }; | |||
int sum = 0; | |||
for (int value : values) { | |||
sum += value; | |||
} | |||
System.out.println(sum); | |||
|nachher=Jetzt wird nur noch <syntaxhighlight inline lang="Java">int</syntaxhighlight> verwendet. Das ist performanter und verbraucht weniger Speicherplatz. | |||
}} | |||
{{Inhaltsblock | |||
|vorher=*; Datenstrukturen | |||
In generisch typparametrisierten Datenstrukturen (z. B. ''Collections'') ist es nicht möglich, primitive Datentypen zu verwenden. Hier werden Wrapperklassen benötigt. | |||
}} | |||
{{Inhaltsblock | |||
|color=green | |||
|vorher=====Positivbeispiel==== | |||
Die Methode <syntaxhighlight inline lang="Java">getData()</syntaxhighlight> gibt eine Liste von <syntaxhighlight inline lang="Java">Double</syntaxhighlight>-Werten zurück, die auch <syntaxhighlight inline lang="Java">null</syntaxhighlight> enthalten kann. | |||
|Beispiel=List<Double> values = getData(); | |||
double highest = 0; | |||
for (Double value : values) { | |||
if (value != null && value > highest) { | |||
highest = value; | |||
} | |||
} | |||
System.out.println(highest); | |||
|nachher=Die Schleifenvariable <syntaxhighlight inline lang="Java">value</syntaxhighlight> muss vom Typ <syntaxhighlight inline lang="Java">Double</syntaxhighlight> sein, um die Möglichkeit von <syntaxhighlight inline lang="Java">null</syntaxhighlight> abzudecken. Die Variable <syntaxhighlight inline lang="Java">highest</syntaxhighlight> kann ein primitiver <syntaxhighlight inline lang="Java">double</syntaxhighlight> sein, da nur der numerische Wert relevant ist. Bevor <syntaxhighlight inline lang="Java">value</syntaxhighlight> zu <syntaxhighlight inline lang="Java">highest</syntaxhighlight> zugewiesen wird, wird überprüft, dass sie nicht <syntaxhighlight inline lang="Java">null</syntaxhighlight> ist. | |||
}} | |||
{{Inhaltsblock | |||
|vorher=*; Vergleiche mit <syntaxhighlight inline lang="Java">equals()</syntaxhighlight> | |||
Bei Wrapperklasseninstanzen handelt es sich nicht mehr um primitive Datentypen. Eine Überprüfung mit dem einfachen Gleichheitsoperator (<syntaxhighlight inline lang="Java">==</syntaxhighlight>) kann ein unerwartetes Ergebnis bringen. Um inhaltliche Gleichheit von zwei Objekten zu prüfen, muss die <syntaxhighlight inline lang="Java">equals()</syntaxhighlight> Methode verwenden werden. | |||
}} | |||
{{Inhaltsblock | |||
|color=red | |||
|vorher=====Negativbeispiel==== | |||
|Beispiel=Integer foo = 128; | |||
Integer bar = 128; | |||
System.out.println(foo == bar); | |||
|nachher=Es wird <syntaxhighlight inline lang="Java">false</syntaxhighlight> ausgegeben, obwohl beide Instanzen den selben Wert beinhalten. | |||
}} | |||
{{Inhaltsblock | |||
|color=green | |||
|vorher=====Positivbeispiel==== | |||
|Beispiel=Integer foo = 128; | |||
Integer bar = 128; | |||
System.out.println(foo.equals(bar)); | |||
|nachher=Nun wird korrekt auf inhaltliche Gleichheit geprüft und es wird <syntaxhighlight inline lang="Java">true</syntaxhighlight> ausgegeben. | |||
}} | |||
{{Inhaltsblock | |||
|color=blue | |||
|vorher=Grundsätzlich sollten Instanzen von Wrapperklassen nur dann verwendet werden, wenn primitive Datentypen nicht möglich sind! Primitive Datentypen sind schneller und resourcenschonender. | |||
}} | |||
<!--##########################################################################--> | |||
<!-- | |||
{{Inhaltsblock | {{Inhaltsblock | ||
|vorher====Verwendung=== | |vorher====Verwendung=== | ||
| Zeile 73: | Zeile 180: | ||
}} | }} | ||
{{Inhaltsblock | {{Inhaltsblock | ||
|vorher=Alle numerischen Wrapperklassen (<syntaxhighlight inline lang="Java">Byte</syntaxhighlight>, <syntaxhighlight inline lang="Java">Short</syntaxhighlight>, <syntaxhighlight inline lang="Java">Integer</syntaxhighlight>, <syntaxhighlight inline lang="Java">Long</syntaxhighlight>, <syntaxhighlight inline lang="Java">Float</syntaxhighlight>, <syntaxhighlight inline lang="Java">Double</syntaxhighlight>) erben von der abstrakten Klasse <syntaxhighlight inline lang="Java">Number</syntaxhighlight>, sodass die folgenden | |vorher=Alle numerischen Wrapperklassen (<syntaxhighlight inline lang="Java">Byte</syntaxhighlight>, <syntaxhighlight inline lang="Java">Short</syntaxhighlight>, <syntaxhighlight inline lang="Java">Integer</syntaxhighlight>, <syntaxhighlight inline lang="Java">Long</syntaxhighlight>, <syntaxhighlight inline lang="Java">Float</syntaxhighlight>, <syntaxhighlight inline lang="Java">Double</syntaxhighlight>) erben von der abstrakten Klasse <syntaxhighlight inline lang="Java">Number</syntaxhighlight>, sodass die folgenden Instanzmethoden immer vorhanden sind: <syntaxhighlight inline lang="Java">byteValue()</syntaxhighlight>, <syntaxhighlight inline lang="Java">shortValue()</syntaxhighlight>, <syntaxhighlight inline lang="Java">intValue()</syntaxhighlight>, <syntaxhighlight inline lang="Java">longValue()</syntaxhighlight>, <syntaxhighlight inline lang="Java">floatValue()</syntaxhighlight>, <syntaxhighlight inline lang="Java">doubleValue()</syntaxhighlight>. Verschiedene Zahlenformate können so einfach umgewandelt werden. Die Methoden werden unter anderem beim unboxing verwendet und beruhen auf [[Cast_außerhalb_der_equals-Methode|expliziter Typumwandlung]]. | ||
|Beispiel=Double foo = 12345.6; | |Beispiel=Double foo = 12345.6; | ||
int bar = foo.intValue(); //12345 | int bar = foo.intValue(); //12345 | ||
| Zeile 128: | Zeile 235: | ||
|beispielname=WrapperklassenEx9 | |beispielname=WrapperklassenEx9 | ||
}} | }} | ||
--> | |||
Aktuelle Version vom 21. Oktober 2025, 12:41 Uhr
| 🚧 | Diese Seite befindet sich in Bearbeitung | 🚧 |
Beschreibung
Als Wrapper bezeichnet man ein Objekt, das ein anderes Objekt verpackt, um dessen Zugriff oder Verhalten zu kontrollieren. Wird in Java von Wrapperklassen gesprochen, sind damit die Klassen gemeint, die primitive Datentypen in Objekte (Referenzdatentypen) verpacken. Zu jedem der acht primitiven Datentypen stellt Java eine Wrapperklasse bereit, die ohne import verwendet werden:
| Primitiver Datentyp | Wrapperklasse |
|---|---|
| boolean | Boolean |
| byte | Byte |
| short | Short |
| char | Character |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
Primitive Datentypen können durch eine Zuweisung in Wrapperklassen ein- und ausgepackt (auto-boxing und auto-unboxing) werden:
Integer foo = 123; //auto-boxing
int bar = foo; //auto-unboxing
null annehmen. Bei primitiven Datentypen ist das nicht möglich. Bei dem Versuch, eine null-Referenz auszupacken, wird eine NullPointerException geworfen.Richtige Verwendung
- Parsen
Häufig liegen Werte von primitiven Datentypen als String vor, z. B. nach Benutzereingaben. Damit diese sicher in den primitiven Datentyp umgewandelt werden können, stellt jede Wrapperklasse, außer Character, eine statische parse*() Methode zur Verfügung. Der * representiert dabei den primitiven Datentyp.
Negativbeispiel
Das folgende Programm versucht "123" in einen int zu überführen.
char[] characters = "123".toCharArray();
int number = 0;
for (char character : characters) {
number = number * 10 + (character - '0');
}
System.out.println(number);
character keine Zahl zwischen 0-9 ist. Sie sollte daher auf keinen Fall verwendet werden.Positivbeispiel
int number = 0;
try {
number = Integer.parseInt("123");
} catch (NumberFormatException e) {
System.out.println("Error, " + e.getMessage());
}
System.out.println(number);
Integer.parseInt()-Methode, die intern bereits alle möglichen Fehler abdeckt. Außerdem ist diese Lösung deutlich verständlicher. Die Ausnahme NumberFormatException sollte immer abgefangen werden, mehr dazu hier.- Primitive Datentypen vor Wrapperklassen
Negativbeispiel
Integer[] values = new Integer[] { 1, 2, 3, 4 };
Integer sum = 0;
for (Integer value : values) {
sum += value;
}
System.out.println(sum);
Integer zu verwenden. Das selbe Ergebnis kann auch mit dem primitiven int erzielt werden. Gleiches gilt auch für einfache VariablenPositivbeispiel
int[] values = new int[] { 1, 2, 3, 4 };
int sum = 0;
for (int value : values) {
sum += value;
}
System.out.println(sum);
int verwendet. Das ist performanter und verbraucht weniger Speicherplatz.- Datenstrukturen
In generisch typparametrisierten Datenstrukturen (z. B. Collections) ist es nicht möglich, primitive Datentypen zu verwenden. Hier werden Wrapperklassen benötigt.
Positivbeispiel
Die Methode getData() gibt eine Liste von Double-Werten zurück, die auch null enthalten kann.
List<Double> values = getData();
double highest = 0;
for (Double value : values) {
if (value != null && value > highest) {
highest = value;
}
}
System.out.println(highest);
value muss vom Typ Double sein, um die Möglichkeit von null abzudecken. Die Variable highest kann ein primitiver double sein, da nur der numerische Wert relevant ist. Bevor value zu highest zugewiesen wird, wird überprüft, dass sie nicht null ist.- Vergleiche mit
equals()
- Vergleiche mit
Bei Wrapperklasseninstanzen handelt es sich nicht mehr um primitive Datentypen. Eine Überprüfung mit dem einfachen Gleichheitsoperator (==) kann ein unerwartetes Ergebnis bringen. Um inhaltliche Gleichheit von zwei Objekten zu prüfen, muss die equals() Methode verwenden werden.
Negativbeispiel
Integer foo = 128;
Integer bar = 128;
System.out.println(foo == bar);
false ausgegeben, obwohl beide Instanzen den selben Wert beinhalten.Positivbeispiel
Integer foo = 128;
Integer bar = 128;
System.out.println(foo.equals(bar));
true ausgegeben.
Grundsätzlich sollten Instanzen von Wrapperklassen nur dann verwendet werden, wenn primitive Datentypen nicht möglich sind! Primitive Datentypen sind schneller und resourcenschonender.