Vorlesung Informatik II Universität Augsburg Wintersemester 2011/2012 Prof. Dr. Bernhard Bauer Folien von: Prof. Dr. Robert Lorenz Lehrprofessur für Informatik 03. JAVA: Grundlagen 1 Primitive Datentypen Es gibt diesselben primitiven Datentypen wie in C Zusätzlich: boolean für Wahrheitswerte byte für Bytes Die Wertebereiche sind ähnlich wie in C festgelegt Es sind diesselben Operatoren wie in C anwendbar Details: Jeder deklarierten Variable wird voreingestellter Wert zugewiesen char: 2 Bytes, nicht-negativ, Unicode hexadezimal byte, short, int, long: Wertebereiche symmetrisch zu 0 byte, short, int, long: 2-Komplement-Darstellung 2 Primitive Datentypen Überblick Name Wertebereich Voreinstellung Operatoren boolean {true,false} false byte 1 Byte 0 short 2 Byte 0 int long char float double 4 8 2 4 8 0 0L \u0000 0.0f 0.0d ==,!=,&,|,^, &&,||,! +,-,+,*,/,%,<, <=,>,>=,==,!=, ~,++,-+,-,+,*,/,%,<, <=,>,>=,==,!=, ++,-... ... ... ... ... Byte Byte Byte Byte Byte 3 Primitive Datentypen Konstanten ähnlich wie in C: 012 0x3F 12 -5 3L 3.7 1.2e+2 'A' \b,\n,\t \", \', \\ \0??? \u???? (Oktalzahl) (Hexadezimalzahl) (positive ganze Zahl) (negative ganze Zahl) (ganze Zahl als long-Wert) (Fließkommazahl) (Exponentialdarstellung) (Buchstabe) (Backspace, Newline, Tabulator) (Sonderzeichen) (Oktalzeichen, 0000 <= 0??? <= 0377) (Unicode-Zeichen, u0000 <= u???? <= uFFFF) 4 Primitive Datentypen Operatoren ähnlich wie in C: Arithmetische Operatoren: Bitarithmetische Operatoren: Logische Operatoren: Vergleichsoperatoren: Zuweisungsoperatoren: Bedingungsoperator: ++, --, +/-, *, /, %, +, ~, <<, >>, >>>, &, |, ^ !, &, ^, |, &&, || <, >, <=, >=, ==, != =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, ?: Operatoren sind überladen, d.h. abhängig vom Datentyp Festgelegte Auswertungsreihenfolge (aber anders wie in C!) * kann nicht zum Dereferenzieren von Pointern benutzt werden! (in Java ist kein direkter Zugriff auf Pointer möglich – später mehr) In Ausdrücken kommt es wie in C zu automatischen Typumwandlungen 5 Primitive Datentypen Automatische Typausweitungen (falls sich in einem Ausdruck Variablen unterschiedlichen Typs befinden) byte short char int long float nach nach nach nach nach nach short, int, long, float, double int, long, float, double int, long, float, double long, float, double float, double double 6 Primitive Datentypen Deklaration wie in C: boolean b = true;//mit Wertzuweisung int i, j;//ohne Wertzuweisung double d = 3.14; char c = 'A'; Durch Deklaration wird der notwendige Speicherplatz für Datentyp reserviert 7 Primitive Datentypen Wertzuweisungen wie in C: boolean b = true;//in der Deklaration b = false;//nach der Deklaration Durch Zuweisung wird einer Variablen ein Wert zugewiesen: Dieser Wert wird also an der reservierten Speicherstelle eingetragen/gespeichert Der Wert kann nur aus dem zugehörigen Wertebereich des Datentyps kommen: Wie in C kommt es zu automatischen Wertumwandlungen (Ausweitung oder Einengung) 8 Primitive Datentypen Explizite Typeinengung durch eine Typcast mittels vorangestelltem (Typ): int i; float b=10.5f; i = (int) b*3;//Wert von i ist 30 (u.U. mit Informationsverlust) 9 Primitive Datentypen Zeiger: In Java gibt es keine Zeiger auf Variablen primitiven Datentyps Parameterübergabe an Funktionen In Java werden Variablen primitiven Datentyps grundsätzlich nach dem “callbyvalue”-Prinzip übergeben (es wird also im Funktionsrumpf mit einer lokalen Kopie gerechnet) Rückgabewerte von Funktionen In Java werden bei primitiven Rückgabetypen grundsätzlich Werte zurückgegeben (niemals Zeiger) 10 Referenz-Datentypen Alle anderen Datentypen sind Klassen oder Felder Beispiele vordefinierte Klassen: String, System, PrintStream, ... (Attribute und Operatoren können der API entnommen werden) Selbstdefinierte Klassen: Siehe UML-Teil Alle Klassen und Felder sind sog. Referenz-Datentypen 11 Klassen Deklaration wie bei primitiven Typen: <Typ> <Vname> Frame f;//ohne Wertzuweisung Variablen einer Klasse sind immer Zeiger Bei der Deklaration wird Speicherplatz für einen Zeiger reserviert 12 Klassen Deklaration wie bei primitiven Typen: <Typ> <Vname> Strings=newString(“Du”);//mit Wertzuweisung Durch new wird dynamisch Speicherplatz für ein Objekt einer Klasse reserviert Die Variable ist ein Zeiger auf diesen Speicherplatz Nach new folgt ein sog. Konstruktor Ein Konstruktor ist eine Operation mit dem gleichen Namen wie die Klasse Ein Konstruktor nimmt eine Initialisierung der Attribute des Objekts vor Konstruktoren können vom Benutzer definiert werden Entspricht in etwa dynamischer Speicherreservierung in C 13 Klassen Wertzuweisungen String s;//Deklaration s=newString(“Hallo”);//Zeiger auf Zeichenkette String t = s;//t zeigt auf diesselbe Stelle wie s s = null;//Null-Referenz: s zeigt nirgendwohin Eine Referenz in Form der Speicheradresse des Objekts der rechten Seite wird in der Variable der linken Seite gespeichert null ist die Nullreferenz (entspricht NULL in C) null ist die Voreinstellung bei Klassen 14 Klassen Wertzuweisungen StringBuffer s1 = new StringBuffer(“Hallo”); //s1 zeigt auf Speicherstelle mit Eintrag “Hallo” StringBuffer s2 = new StringBuffer(“World”); //s2 zeigt auf Speicherstelle mit Eintrag “World” Stringbuffer ist eine weitere vordefinierte Bibliotheksklasse zur Verwaltung von Zeichenketten 15 Klassen Wertzuweisungen s2 = s1; //s1 und s2 zeigen auf Speicherstelle mit Eintrag “Hallo” s2.append(“Du”); //s1 und s2 zeigen auf Speicherstelle mit Eintrag “HalloDu” append ist eine Operation der Klasse StringBuffer append erweitet den Speicherbereich und hängt eine Zeichenkette hinten an 16 Klassen Zeiger: Alle Variablen einer Klasse sind Zeiger Parameterübergabe an Funktionen In Java werden Variablen einer Klasse grundsätzlich nach dem “callbyreference”-Prinzip übergeben (damit sind die Objekte im Funktionsrumpf manipulierbar, aber natürlich nicht die Zeiger selbst) Rückgabewerte von Funktionen In Java werden bei Klassen-Rückgabetypen grundsätzlich Zeiger zurückgegeben (niemals die Objekte selbst) 17 Klassen Parameterübergabe und Rückgabewerte StringBuffer test(StringBuffer s1,StringBuffer s2) { s1 = s2.append(s1); return s1; } public static void main(String args[]){ StringBuffers1=newStringBuffer(“Hallo”); StringBuffers2=newStringBuffer(“World”); StringBuffer s3 = test(s1,s2); } s1 zeigt auf Speicherstelle mit Eintrag “Hallo” s2 zeigt auf Speicherstelle mit Eintrag “WorldHallo” s3 zeigt auf Speicherstelle mit Eintrag “WorldHallo” 18 Klassen Typumwandlungen Unter bestimmten Umständen können Klassen ineinander umgewandelt werden Mehr dazu im UML-Teil (Ober- und Unterklassen) 19 Arrays (Felder) Wie in C kann man Felder beliebigen Datentyps mit fester Länge definieren Wie in C sind Feld-Variablen Zeiger Deklaration: <Typ> <meinArray>[] Sorgt für Speicherreservierung für einen Zeiger auf <Typ> Initialisiert den Zeiger auf null (im Unterschied zu C) Längenfestlegung und Speicherreservierung für das Feld erst bei Erzeugung (im Unterschied zu C) 20 Arrays Wie in C kann man Felder beliebigen Datentyps mit fester Länge definieren Wie in C sind Feld-Variablen Zeiger Erzeugung: <meinArray> = new <Typ>[<Länge>] Reserviert Speicherplatz für alle Elemente des Feldes Der Wert der Variable ist ein Zeiger auf diesen Speicherplatz (auf das erste Feldelement) 21 Arrays Wie in C kann man Felder beliebigen Datentyps mit fester Länge definieren Wie in C sind Feld-Variablen Zeiger Zugriff auf Elemente über Index: <meinArray>[i] Ist ein Name für das (i+1)-te Element des Feldes (man fängt wie in C bei 0 zu zählen an) Im Unterschied zu C ist keine explizite Zeigerarithmetik (Adressverschiebung) möglich Java-Programme sollen Plattform-unabhängig und portabel sein 22 Arrays Beispiele int[] meinArray = { 3, 5, 9 }; int[] meinArray = new int[20]; int[][] arr2D = new int[9][8]; String[] arr = { "ab", "mn", "xy" }; String[] arr = new String[2]; MyClass[] myArr = new MyClass[22]; myArr[i] = new MyClass(); 23 Arrays Weitere Besonderheiten: Länge eines Arrays abfragbar mit <Variablename>.length: int n = meinArray.length; Felder kopieren mit System.arraycopy: System.arraycopy(arr1,0,arr2,0,arr2.length); Vordefinierte Bibliotheksklassen für Felder variabler Länge und gemischten Typs: LinkedList, ArrayList, HashSet, TreeSet, HashMap, TreeMap, Vector, ... (siehe später auch UML) 24 Zeiger Zusammenfassung In Java gibt es keine explizite Dereferenzierung Es gibt keine Zeiger auf Werte primitiven Typs Alle Variablen nichtprimitiven Typs sind Zeiger Für Variablen nichtprimitiven Typs wird mit new <Konstruktor>(<Parameterliste>) Speicherplatz für ein Objekt des Typs reserviert und werden die Komponenten initialisiert 25 Zeiger Zusammenfassung Nicht mehr benutzter, dynamisch reservierter Speicherbereich wird automatisch wieder freigegeben (Garbage Collection) Löschung von Objekten, auf die kein Zeiger mehr zeigt dazu: Variablen von unbenötigten Objekten immer null- Referenz zuweisen! 26 Funktionen Funktionen sind immer Teil einer Klasse Deklaration Genauso wie in C in der Form <Rückgabetyp> <Funktionsname>(<Parameterliste>) mit <Parameterliste> := <Typ1> <Parameter1>, ... 27 Funktionen Funktionen sind immer Teil einer Klasse Aufruf Über Punkt-Operation, angewendet auf Variable der Klasse oder den Klassennamen selbst bei static-Funktionen: <Variable>.<Funktionsname>(<Werte>) <Klassenname>.<Funktionsname>(<Werte>) Ähnlich wie Zugriff auf Komponenten von strukturierten Datentypen in C Wie in C müssen Werte zu Eingabeparametern passen 28 Kontrollstrukturen Fallunterscheidungen wie in C: if(<Bedingung>) { <Anweisungen> } else { <Anweisungen> } switch(<Ausdruck>){ case <Wert>: <Anweisungen> default: <Anweisungen> } 29 Kontrollstrukturen Wiederholungen wie in C: while(<Bedingung>) { <Anweisungen> } do { <Anweisungen> } while(<Bedingung>); for(<Wertzuweisung>;<Bedingung>;<Anweisung>) { <Anweisungen> } 30 Hüllklassen Java stellt Hüllklassen (wrapper classes) für die primitiven Datentypen zur Verfügung: Konstruktoren machen aus Elementen primitiven Typs Objekte: public <Hüllklasse> (<Datentyp> <value>) Umkehrmethoden gewinnen die Elemente primitiven Typs zurück: public <Datentyp> <Datentyp>Value() Verfügbare Hüllklassen: Boolean (zu boolean), Character (zu char), Number (abstrakte Oberklasse für alle Zahlklassen), Integer (zu int), Long (zu long), Float (zu float), Double (zu double) 31 Zeichenketten Im Gegensatz zu C gibt es in Java für Zeichenketten eigene Datenstrukturen Für die Repräsentation von Zeichenketten gibt es vordefinierte Bibliotheksklassen Diese Klassen definieren verschiedene Zeichenketten-Operationen verschiedene Konstruktoren zur Erzeugung von Zeichenketten-Objekten 32 Zeichenketten Klasse String repräsentiert Zeichenketten mit zahlreichen Operationen Zeichenketten sind konstant, d.h. es gibt keine Operationen zum Ändern einer einmal konstruierten Zeichenkette 33 Zeichenketten Klasse String Konstruktoren (Auswahl) String() String(char[] value) wandelt das char-Feld value in einen String um String(String value) Kopierkonstruktor String(StringBuffer buffer) Wandelt buffer in einen String um 34 Zeichenketten Klasse String Operationen (Auswahl) int length()//Länge char charAt (int index)//Buchstabe an Position index String toUpperCase()//Umwandlung in Großbuchstaben int compareTo (String anotherString)//Lexikographisch vergleichen boolean startsWith(String prefix)//Ist prefix ein Anfangsstück? int indexOf(int ch)//Erster Index eines Zeichens String substring(int beginIndex, int endIndex)//Substring String concat (String str)//String str anhängen String replace(char oldChar, char newChar)//Buchstaben ersetzen //…u.v.m. 35 Zeichenketten Klasse String Operationen zur Typumwandlung static String valueOf(<Typ> val) Umwandlung nach String für jeden Grundtyp <Typ> außer byte und short <Hüllklasse>(String str) Umwandlung von String in Hüllklasse char[] toCharArray() Umwandlung in ein neues char-Feld (und einige mehr) 36 Zeichenketten Klasse StringBuffer Repräsentiert dynamische Zeichenketten, die nach ihrer Konstruktion beliebig modifiziert werden können. Initialisierung mit einer leeren Zeichenkette fester Länge 37 Zeichenketten Klasse Stringbuffer Operationen (Auswahl) StringBuffer insert(int offset, Object obj)//Einfügen Objekt StringBuffer insert(int offset, String str) //Einfügen String StringBuffer insert(int offset, float f) //Einfügen Zahl StringBuffer insert(int offset, int i) //Einfügen ganze Zahl StringBuffer delete(int start, int end)//Entfernen von Zeichen StringBuffer deleteCharAt(int index)/Entfernen eines Zeichens int capacity()//liefert Kapazität der Speicherstelle int length() //liefert die Länge der aktuellen Zeichenkette char charAt(int index)//liefert ein Zeichen …(u.v.m.) 38 API Application Programming Interface http://java.sun.com/j2se/1.4.2/docs/api/ Klassenbibliothek mit vordefinierten Java-Klassen Aufgeteilt in Pakete, u.a.: java.lang //Basisklassen (Automatisch eingebunden) System, Thread, Zeichenketten,... java.util //Utilities Häufige Datenstrukturen, Zeit/Datum, Zufallszahlen,... java.io //Ein- und Ausgabe Datenströme (Ein-/Ausgabe), Lesen/Schreiben von Dateien,... java.awt //grafische Ausgabe Fenster, Schaltflächen, Textfelder, Menüs, ... 39 API Application Programming Interface http://java.sun.com/j2se/1.4.2/docs/api/ Klassenbibliothek mit vordefinierten Java-Klassen Import von Paketen der API am Programmanfang: import paketname.*; Macht Klassen und Funktionen benutzbar Ähnlich dem include-Befehl in C 40