Objektorientierte Programmierung. Kapitel 20: Wrapper-Klassen

Ähnliche Dokumente
1 Polymorphie (Vielgestaltigkeit)

Java Einführung VARIABLEN und DATENTYPEN Kapitel 2

Java für Computerlinguisten

Objektorientierte Programmierung. Kapitel 12: Interfaces

Kapitel 6. Vererbung

Kapitel 6. Vererbung

Kapitel 6. Vererbung

Ein erstes Java-Programm

5.4 Klassen und Objekte

Distributed Computing Group

3 Objektorientierte Konzepte in Java

Algorithmen und Datenstrukturen

3 Objektorientierte Konzepte in Java

A(T1) A(T2) A(T1) A(T2)

Java Kurs für Anfänger Einheit 5 Methoden

Prinzipielle Ausführungsvarianten I

Vererbung & Schnittstellen in C#

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Auszug aus. C sharp. Galileo Computing. Ein Service von. Tutorial und Referenz. von Eric Gunnerson

Computeranwendung und Programmierung (CuP)

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Testen mit JUnit. Motivation

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

Java Generics & Collections

C# im Vergleich zu Java

Klassenbeziehungen & Vererbung

Gliederung. Tutorium zur Vorlesung. Gliederung. Gliederung. 1. Gliederung der Informatik. 1. Gliederung der Informatik. 1. Gliederung der Informatik

Algorithmen und Datenstrukturen 07

Vererbung. Vererbung von Methoden und Instanzvariablen. Vererbung als Realisierung einer is-a Beziehung.

Kontrollstrukturen, Pseudocode und Modulo-Rechnung

4. Datentypen. Einleitung Eingebaute Datentypen. Konversion / Type-Cast. Operatoren. Übersicht Die Datentypen char, float und double Standardwerte

Datenbankanwendungsprogrammierung Crashkurs Java

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Javakurs für Anfänger

Einführung in die Informatik für Hörer aller Fakultäten II. Andreas Podelski Stephan Diehl Uwe Waldmann

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Modul 122 VBA Scribt.docx

Repetitorium Informatik (Java)

Dynamische Sprachen auf der JVM

VIII: Vererbung. Unterklassen einer Klasse. Vererbung von Methoden und Instanzvariablen. Überschreiben von Methoden

Java Schulung (Java 2 Java Development Kit 5 / 6)

Hochschule Darmstadt Fachbereich Informatik

Kapitel 11: Wiederholung und Zusammenfassung

Programmieren in C. C Syntax Datentypen, Operatoren und Kontrollstrukturen. Prof. Dr. Nikolaus Wulff

Test zu Grundlagen der Programmierung Leitung: Michael Hahsler. 21. November 2003

Javakurs 2013 Objektorientierung

J.5 Die Java Virtual Machine

Typumwandlungen bei Referenztypen

Schnittstellen implementieren am Beispiel Suchbaum

equals und hashcode SortedSet NavigableSet Assoziative Container Programmieren II Dr. Klaus Höppner Hochschule Darmstadt Sommersemester / 32

Grundlagen von Python

Einführung in Java. PING e.v. Weiterbildung Andreas Rossbacher 24. März 2005

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure

2 Einfache Rechnungen

Java: Vererbung. Teil 3: super()

Objective-C CheatSheet

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

2.4.3 Polymorphie (Wiederholung von Alp2)

Objektorientierte Programmierung

Hadoop I/O. Datenintegrität Kompression Serialisierung Datei-basierte Datenstrukturen Prof. Dr. Christian Herta 1/29

Let s get started with Java

Probeklausur: Programmierung WS04/05

Programmiertechnik Operatoren, Kommentare, Ein-/Ausgabe

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

Noch für heute: primitive Datentypen in JAVA. Primitive Datentypen. Pseudocode. Dezimal-, Binär- und Hexadezimalsystem. der logische Typ boolean

Übungsblatt 3: Algorithmen in Java & Grammatiken

Dr. Monika Meiler. Inhalt

Java Tipps für Lehrer. Table des matières. Einleitung

Repräsentation von Daten Binärcodierung von rationalen Zahlen und Zeichen

Algorithmische Kernsprache. Zuweisung, einfache und bedingte Anweisung, Blöcke, Schleifen, return, debugging.

Numerische Datentypen. Simon Weidmann

Meeting C++ C++11 R-Value Referenzen

Programmierkurs Java

C++ - Einführung in die Programmiersprache Polymorphismus und Vererbung. Eltern

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 8. Arrays. Arrays

Abschnitt 9: Schnittstellen: Interfaces

Programmiertechnik Skalare Typen,Variablen, Zuweisungen

Java-Schulung Grundlagen

Themen des Kapitels. 2 Grundlagen von PL/SQL. PL/SQL Blöcke Kommentare Bezeichner Variablen Operatoren. 2.1 Übersicht. Grundelemente von PL/SQL.

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Primitive Datentypen

Objektorientierte Programmierung

Methoden. von Objekten definiert werden, Methoden,, Zugriffsmethoden und Read-Only

Programmieren in Java

Java für C++ Programmierer

Software Engineering Klassendiagramme Einführung

C/C++-Programmierung

Objektorientierte Programmierung. Kapitel 9: Arrays

Programmieren I. Prinzipieller Ablauf. Eigenschaften von JAVA. Source-Code Javac Bytecode. Java Virtual Machine (Java, Browser, Appletviewer)

C# anhand von ECMA-334. Das große Seminar WS 04/ Daniel Wiese

Deklarationen in C. Prof. Dr. Margarita Esponda

VisualBasic - Variablen

Objektorientiertes Programmieren für Ingenieure

Persistenz von Objekten relationale Datenbank Eigene Datenstruktur XML (JAXB) Proprietäre Dateiformate (Lochkarten)

5.6 Vererbung. Vererbung

Vorlesung Objektorientierte Programmierung Probeklausur

C++-Zusammenfassung. H. Schaudt. August 18, 2005

Objektorientierte Programmierung

Transkript:

20. Wrapper-Klassen 1/27 Objektorientierte Programmierung Kapitel 20: Wrapper-Klassen Stefan Brass Martin-Luther-Universität Halle-Wittenberg Wintersemester 2013/14 http://www.informatik.uni-halle.de/ brass/oop13/

20. Wrapper-Klassen 2/27 Inhalt 1 Einführung und Motivation 2 Methoden 3 Boxing und Unboxing

20. Wrapper-Klassen 3/27 Einführung und Motivation (1) Die Typen in Java gliedern sich in Primitive Typen und Referenz-Typen. Für Referenz-Typen ist Object ein gemeinsamer Obertyp. D.h. man kann einen beliebigen Wert eines Referenztyps (Klasse, Interface, Array) einer Variablen vom Typ Object zuweisen. Z.B. für Methoden praktisch: An einen Parameter vom Typ Object kann man jeden Wert eines Referenztyps binden. Wenn man allgemein verwendbare Datenstrukturen wie z.b. Listen programmiert, kann man als Element-Typ Object verwenden, und jeden Referenztyp speichern.

20. Wrapper-Klassen 4/27 Einführung und Motivation (2) Für Werte primitiver Typen geht dies zunächst nicht: Sie sind grundlegend anders als Referenztypen. Z.B. belegen Variablen von einem Referenztyp alle gleich viel Speicher (die genaue Größe ist nicht vorgeschrieben, 32 Bit wären aber typisch). Ein double benötigt (mindestens) 64 Bit, ein byte dagegen nur 8 Bit. Object ist kein Obertyp von primitiven Typen. Damit man Werte primitiver Typen aber doch an Methoden übergeben kann, die einen Parameter vom Typ Object haben, wurden die Wrapper-Klassen eingeführt: z.b. kann man einen int-wert in einem Objekt der Klasse Integer verpacken / einwickeln (engl. to wrap ). Deutsch werden sie manchmal auch als Hüllklassen genannt. Es gibt eine solche Klasse für jeden primitiven Typ.

20. Wrapper-Klassen 5/27 Einführung und Motivation (3) Im Prinzip enthält ein Objekt vom Typ Integer also einen einzelnen int-wert: Diesen Wert muß man bei der Objekterzeugung angeben (Parameter des Konstruktors), z.b. Integer o = new Integer(3); Man kann den Wert mit der Methode intvalue() wieder abfragen: int i = o.intvalue(); // i ist 3 Die Methode heißt intvalue() und nicht einfach value(), weil es auch andere Methoden gibt, mit denen man automatisch eine Typumwandlung durchführen kann, s.u. Der im Objekt gespeicherte Wert ist nicht änderbar.

20. Wrapper-Klassen 6/27 Einführung und Motivation (4) Da Integer eine Klasse ist, vergleicht == die Referenzen und nicht den Inhalt: Integer o1 = new Integer(3); Integer o2 = new Integer(3); if(o1 == o2) System.out.println("gleich"); else System.out.println("verschieden"); Dieses Testprogramm druckt verschieden aus. Die Methode equals(...) vergleicht wie üblich den Inhalt: if(o1.equals(o2)) System.out.println("Aber equals ist true!"); Die Bedingung ist wahr, die Ausgabe wird also ausgeführt.

20. Wrapper-Klassen 7/27 Einführung und Motivation (5) Tabelle der Wrapper-Klassen: Primitiver Typ Wrapper-Klasse boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double Dem Namen der Klasse ist jeweils ein Link zur Dokumentation hinterlegt. Meist heißt die Klasse wie der primitive Typ, nur mit großem Anfangsbuchstaben. Ausnahmen sind nur Integer und Character.

20. Wrapper-Klassen 8/27 Einführung und Motivation (6) Es gibt eine gemeinsame abstrakte Oberklasse Number für Byte, Short, Integer, Long, Float, Double. [http://docs.oracle.com/javase/7/docs/api/java/lang/number.html] Diese Klasse hat noch weitere Unterklassen, z.b. BigInteger und BigDecimal für beliebig große Zahlen. Jede Wrapper-Klasse T implementiert das Interface comparable<t>, (mit der Methode compareto(...)). Und das Interface Serializable. Die Klassen haben auch (s.u.) statische Methoden für den jeweiligen primitiven Typ, z.b. parseint(...) zur Umwandlung von Strings in den Typ, Konstanten für Begrenzungen des Zahlbereichs.

20. Wrapper-Klassen 9/27 Inhalt 1 Einführung und Motivation 2 Methoden 3 Boxing und Unboxing

20. Wrapper-Klassen 10/27 Methoden (1) Alle numerischen Wrapper-Klassen erlauben es, den im Objekt gespeicherten Wert mit verschiedenen Typen abzufragen: byte bytevalue() short shortvalue() int intvalue() long longvalue() float floatvalue() double doublevalue() Natürlich wird man im Normalfall die Methode für den jeweils gespeicherten Typ verwenden. Man kann so aber eine Typ-Umwandlung durchführen, z.b. runden. Wie bei einem expliziten Typ-Cast werden im Notfall Bits abgeschnitten und der Wert möglicherweise zerstört. Es gibt dabei keine Exception.

20. Wrapper-Klassen 11/27 Methoden (2) Für die beiden anderen Klassen bekommt den gespeicherten Wert entsprechend mit charvalue() für Objekte der Klasse Character booleanvalue() für Objekte der Klasse Boolean. Außerdem gibt es natürlich die von der Klasse Object ererbten Methoden, insbesondere boolean equals(object obj) String tostring() Und die Methode des comparable<t>-interfaces, z.b. für die Klasse Integer: int compareto(integer o) 0/positiv/negativ, falls Wert in this gleich/größer/kleiner als Wert in o.

20. Wrapper-Klassen 12/27 Erzeugung von Objekten Alle Wrapper-Klassen (mit Ausnahme von Character) haben zwei Konstruktoren (Character nur den ersten): einen mit einem Argument von dem jeweiligen primitiven Typ, Float hat zusätzlich einen Konstruktor mit double-argument. einen mit einem Argument vom Typ String, z.b. Integer obj = new Integer("123"); Bei den Zahl-Typen gibt es notfalls eine NumberFormatException. Außerdem gibt es eine statische Methode valueof(...), die ein Objekt der jeweiligen Wrapper-Klasse liefert: Integer obj = Integer.valueOf(3); Wie beim Konstrukor gibt es Varianten mit dem jeweiligen Typ, und mit einem String als Parameter (außer bei Character). Bei den ganzzahligen Typen gibt es noch eine dritte Variante, bei der man die Basis wählen kann (z.b. 8 für oktal).

20. Wrapper-Klassen 13/27 Umwandlung zwischen Wert und String (1) Eine Umwandlung von einer Zeichenkette in ein Objekt der Wrapper-Klasse ist möglich mit Konstruktor mit Parameter vom Typ String, statische Methode valueof(string s). Eine Umwandlung von einem Objekt der Wrapper-Klasse in einen String ist möglich mit Methode tostring(): Von Object geerbt. Methode tostring(int radix): Hier kann man noch die Basis angeben, z.b. 16 für Hexadezimaldarstellung. Die Klasse enthält aber auch statische Methoden, um direkt zwischen einem Wert des primitiven Typs und String umzuwandeln (siehe nächste Folie).

20. Wrapper-Klassen 14/27 Umwandlung zwischen Wert und String (2) Eine Umwandlung von einer Zeichenkette in einen Wert des primitiven Typs ist möglich mit der statischen Methode static T parset(string s), wobei T durch den primitiven Typ zu ersetzen ist, z.b. int i = Integer.parseInt("123"); Nur Character hat das nicht. Die ganzzahligen Typen haben außerdem eine Variante mit zweiten Argument für die Basis, sowie die Methode decode(string s), die einen Präfix wie 0x für Basis 16 berücksichtigt. Die Umwandlung eines Wertes eines primitiven Typs in eine Zeichenkette ist möglich mit der statischen Methode static String tostring(t n), wobei T der Typ ist. Die Klassen Integer/Long haben außerdem eine Variante mit zweitem Argument für die Basis, sowie Methoden wie tohexstring(int i), tooctalstring(int i), tobinarystring(int i) für spezielle Basen.

20. Wrapper-Klassen 15/27 Weitere Statische Methoden (1) Die Klasse Character statische Methoden u.a. zur Unicode-Unterstützung, z.b. static int tocodepoint(char high, char low) Viele Methoden sind dupliziert, und arbeiten entweder mit dem vollen Unicode-Bereich (int), oder mit UTF-16 Einheiten (char). Zeichen-Klassifizierung, z.b. static boolean isletter(char ch) Umwandlung zwischen Groß- und Kleinbuchstaben, z.b. static char touppercase(char ch) Umwandlung zwischen Ziffern und Zahlen, z.b. static int digit(char ch, int radix) Die umgekehrte Abbilung erhält man mit static char fordigit(int d, int radix).

20. Wrapper-Klassen 16/27 Weitere Statische Methoden (2) Integer hat verschiedene statische Funktionen zum Arbeiten mit ganzen Zahlen auf Bitebene. Z.B. liefert static int bitcount(int i) die Anzahl von 1 Bits, und static int numberofleadingzeros(int i) die Anzahl führender Nullen. Double hat Methoden isnan und isinfinite zum Test auf spezielle Werte, Es gibt diese Methoden jeweils als normale Methode ohne Parameter (dann wird der Wert aus dem Objekt genommen), und als statische Methode mit double-parameter. Methoden doubletolongbits und longbitstodouble, um zwischen double-wert und interner Bit-Darstellung umrechnen zu können.

20. Wrapper-Klassen 17/27 Konstanten Die Wrapper-Klassen für die numerischen Typen haben Konstanten für die Begrenzung des Zahlbereiches: MIN_VALUE: Kleinstmöglicher Wert Z.B. ist Integer.MIN_VALUE = 2 31 = 2 147 483 648. MAX_VALUE: Größtmöglicher Wert Z.B. ist Integer.MAX_VALUE = 31 1 = 2 147 483 647. SIZE: Speichergröße in Bits Z.B. ist Integer.SIZE = 32. Für die Gleitkomma-Typen gibt es weitere Konstanten, z.b. NaN ( not a number : Fehlerwert). Die Klasse Character hat viele Konstanten für die Unicode-Unterstützung.

20. Wrapper-Klassen 18/27 Inhalt 1 Einführung und Motivation 2 Methoden 3 Boxing und Unboxing

20. Wrapper-Klassen 19/27 Boxing und Unboxing (1) Wenn man vor Java 5 mit dem Wert im Objekt einer Wrapper-Klasse rechnen wollte, musste man explizit den Wert aus dem Objekt herausholen, z.b. mit der Methode intvalue(), dann mit dem Wert des primitiven Typs rechnen, anschließend explizit ein neues Objekt erzeugen. Das sieht z.b. so aus (mit Variable obj vom Typ Integer): obj = new Integer(obj.intValue() + 1); Seit Java 5 fügt der Compiler den Methoden-Aufruf und die Objekt-Erzeugung automatisch ein: obj = obj + 1;

20. Wrapper-Klassen 20/27 Boxing und Unboxing (2) Intern geschehen bei obj = obj + 1; die gleichen drei Schritte, wie oben genannt: Wert auspacken, eins addieren, neues Objekt erzeugen mit dem neuen Wert. Die Objekte der Wrapper-Klassen sind ja unveränderlich. Man kann also nicht einfach in dem existierenden Objekt den Wert ändern, sondern es muss ein neues Objekt erzeugt werden. Wenn es keine anderen Referenzen auf das alte Objekt gibt, wird es wahrscheinlich nach einiger Zeit vom Garbage Collector eingesammelt und recycled. Tatsächlich kann man sogar obj++; schreiben: Auch hier wird ein neues Integer-Objekt mit dem um eins größeren Wert erzeugt und in obj gespeichert. D.h. die Referenz in obj zeigt jetzt auf das neue Objekt.

Boxing und Unboxing (3) Das Aus- und Einpacken ist auch einzeln nützlich. Eine Methode mit Parameter vom Typ Object, z.b. static void m(object o) {... } kann man auch mit Werten beliebiger primitiver Typen aufrufen, ohne explizit eine Umwandlung in ein Objekt aufschreiben zu müssen: m(5); Intern wird ein Objekt vom Typ Integer erzeugt (mit dem Wert 5), und dieses Objekt an die Methode übergeben. Object ist (indirekte) Oberklasse aller Klassen, auch von Integer. Dies ist das Auto-Boxing (oder einfach Boxing ). Das Gleiche geschieht bei der einfachen Zuweisung Integer obj = 5; 20. Wrapper-Klassen 21/27

20. Wrapper-Klassen 22/27 Boxing und Unboxing (4) Das automatische Auspacken ( Auto-Unboxing oder einfach Unboxing ) ist z.b. nützlich, wenn man ein Objekt einer Wrapper-Klasse mit einem Wert eines primitiven Typs vergleicht: if(obj == 100) {... } Das ist kein Typfehler, sondern es wird der in obj gespeicherte Wert mit 100 verglichen. Natürlich ist es nur dann kein Typfehler, wenn obj einer numerischen Wrapper-Klasse angehört. Das Auto-Unboxing ist eine Spezialbehandlung der Wrapper-Klassen, die man nicht für eigene Klassen haben kann. Falls obj die Null-Referenz enthält, gibt es eine NullPointerException. Wenn natürlich auf beiden Seiten vom == ein Objekt einer Wrapper-Klasse steht, werden die Referenzen verglichen, nicht die gespeicherten Werte.

20. Wrapper-Klassen 23/27 Boxing und Unboxing (5) Weil dagegen bei <= u.s.w. immer ausgepackt wird, kann folgende paradoxe Situation auftreten: x <= y x >= y, x!= y und aber (wenn x und y den gleichen Wert enthalten). Überraschung: Autoboxing erzeugt nicht immer neue Objekte, sondern nimmt für kleine Zahlen vorgefertigte Objekte: Integer o1 = 5; // implizit: Integer.valueOf(5); Integer o2 = 5; if(o1 == o2) // ist wahr! System.out.println("Gleiches Objekt!"); Dies gilt für alle Werte der Typen boolean und byte, für char-werte, die ASCII-Codes entsprechen (bis 127), und für short und int von 128 bis +127.

20. Wrapper-Klassen 24/27 Automatische Typ-Anpassungen (1) Die Liste der automatischen Typ-Anpassungen bei Zuweisungen muss nun erweitert werden: Widening primitive conversions : Von einem kleineren primitiven Typ zu einem größeren, z.b. int double. Widening reference conversions : Von einer Unterklasse zu einer Oberklasse (oder implementierten Interface, allgemein Obertyp), z.b. Student Person. Boxing conversion, optionally followed by a widening reference conversion : Z.B. int Integer Object. Unboxing conversion, optionally followed by a widing primitive conversion : Z.B. Integer int double.

20. Wrapper-Klassen 25/27 Automatische Typ-Anpassungen (2) Automatische Typ-Anpassungen bei Zuweisungen, Forts.: Falls rechts ein konstanter Ausdruck steht, und er passt in den kleinen ganzzahligen Typ links, sind auch verkleinernde Umwandlungen ( narrowing primitive conversions ) möglich, z.b. von 5 (formal ein int) nach byte oder Byte. Nach den obigen Regeln geht z.b. Boxing nicht mehr nach einer Erweiterung des primitiven Typs, und tatsächlich liefert folgende Zuweisung einen incompatible types Fehler: Double d = 1; // Falsch! Die Umwandlungs-Kette int double Double geht also nicht. Bei Bedarf muss man 1.0 schreiben, oder auch (double) 1. Die Regeln gelten (bis auf die Ausnahme für konstante Ausdrücke) auch für die Parameter-Übergabe.

20. Wrapper-Klassen 26/27 Automatische Typ-Anpassungen (3) Bei Operatoren wie den vier Grundrechenarten, numerischen Vergleichen wie < etc. wird die Binary Numeric Promotion angewendet: Ist einer der beiden Operanden von einem Referenztyp, wird Unboxing durchgeführt. Das geht nur für die 8 Wrapper-Klassen, sonst hat man einen Typfehler. Ist dann einer der Operanden von Typ double, wird der andere nach double konvertiert. Ansonsten, ist einer vom Typ float, wird der andere nach float konvertiert. Sonst: Ist einer long, wird der andere nach long konvertiert. Sonst werden beide nach int konvertiert. Auch bei der Addition von zwei byte-werten wird also mit int gerechnet.

20. Wrapper-Klassen 27/27 Automatische Typ-Anpassungen (4) Ist bei + einer der Operanden (egal ob links oder rechts) vom Typ String, wird auf den anderen die String Conversion angewendet: Formal wird ein Wert eines primitiven Typs zuerst in eine Wrapper-Klasse umgewandelt, z.b. mit Integer(x). Die Typen byte und short werden auch nach Integer umgewandelt, ansonsten jeder primitive Typ in seine zugehörige Wrapper-Klasse. Danach gibt es also nur noch Referenz-Typen. Ist der Wert null, wird dieser in den String "null" umgewandet. Hier gibt es also keine NullPointerException. Sonst geschieht die Umwandlung durch Aufruf der Methode tostring(), die schon in Object definiert ist, aber in Subklassen überschrieben sein kann. Insbesondere ist sie in den Wrapper-Klassen überschrieben.