Inhaltsverzeichnis

Werbung
Softwaretechnik, Mitschrift 2. Semester
Inhaltsverzeichnis
Seite
1. EINFÜHRUNG .....................................................................................2
1.1 Eigenschaften von Java ................................................................................. 2
1.2 Erste Beispiele ................................................................................................ 2
2. VARIABLEN, TYPEN UND OPERATOREN ....................................... 7
2.1 Variablen.......................................................................................................... 7
2.2 Der Typ boolean .............................................................................................. 7
2.3 Der Typ byte .................................................................................................... 8
2.4 Besondere Operationen ................................................................................. 9
2.5 Gleitkommatypen .......................................................................................... 11
2.6 Typumwandlung............................................................................................ 12
2.6 String.............................................................................................................. 14
2.7 Arrays............................................................................................................. 15
3. ELEMENTARE JAVA - ANWEISUNGEN.......................................... 18
3.1 Allgemeines................................................................................................... 18
3.2 Methoden ....................................................................................................... 18
3.3 Statements..................................................................................................... 19
3.4 IF – Anweisungen.......................................................................................... 19
3.5 Switch – Anweisung ..................................................................................... 21
3.6 Schleifen ........................................................................................................ 22
3.7 break- und continue – Anweisungen........................................................... 24
3.8 return – Anweisung....................................................................................... 24
4. KLASSEN UND OBJEKTE IN JAVA ................................................ 25
4.1 Objekte........................................................................................................... 25
4.2 Klassen .......................................................................................................... 25
4.3 Deklarationen ................................................................................................ 28
4.4 Methoden ....................................................................................................... 30
4.5 Konstruktoren ............................................................................................... 32
4.6 Schlüsselwort this ........................................................................................ 33
4.7 Gültigkeitsbereich......................................................................................... 34
4.7 Methodenaufrufe und Parameterübergabe................................................. 36
4.8 Objektfreigabe ............................................................................................... 36
© S. Meißner & A.Vogl
Seite 1
Softwaretechnik, Mitschrift 2. Semester
1. Einführung
Java wurde entwickelt von James Gosling und Bill Joy. 1995 wurde die Software von Sun
vorgestellt.
1.1 Eigenschaften von Java
Allgemeine Eigenschaften von Java:
•
•
•
•
•
•
•
objektorientiert
Begriffe: Klassen, Objekte, Methoden, Attribute, Vererbung, Polymorphie usw.
Plattformunabhängig
Sicher
Robust
Exception
Handling
(Ausnahmebehandlung)
Erweiterbar
Multithreaded - quasi-parallele Abläufe
Man
erstellt
einen
Java-Bytecode.
Zur
Interpretation wird die Java virtuelle Maschine
(JVM) verwendet. Die Datei Cbeispiel.java wird
vom Java-Compiler in Cbeispiel.class gewandelt
und vom Java Interpreter ausgelesen.
Java besteht aus:
•
•
•
der Sprache selbst (Gegenstand der Vorlesung)
Java virtuelle Maschine
Klassenbibliotheken
- sehr umfangreich
- mit jar -xvf src.jar die java-Klassen entpacken
1.2 Erste Beispiele
Erstellung einer Beispieldatei „Hello World“.
a) Eine Klasse mit Notepad schreiben. Kompilieren unter DOS (javac CHello.java).
Ausführen unter DOS (java CHello.class).
b) Mit JBuilder. Schritt 1: Projekt anlegen. Schritt 2: Neue Klasse zum Projekt
hinzufügen. Schritt 3: Klasse schreiben. Schritt 4: übersetzen und ausführen
© S. Meißner & A.Vogl
Seite 2
Softwaretechnik, Mitschrift 2. Semester
© S. Meißner & A.Vogl
Seite 3
Softwaretechnik, Mitschrift 2. Semester
Projekt
Editor
Komponenten
baum
Wir geben nun folgenden Code in den Editor ein:
// Paketname
package helloword;
// Importieren aller Klassen von java.lang
import java.lang.*;
// Object als Urahn aller Klassen
public class CHelloWorld extends Object {
public static void main(String args[]) {
// Ausgabe auf das Standardausgabegerät
System.out.println("Hello World!");
}
}
© S. Meißner & A.Vogl
Seite 4
Softwaretechnik, Mitschrift 2. Semester
Einige wichtige Schlüsselwörter:
•
•
•
•
•
•
•
•
Wortzwischenraumzeichen: Leerzeichen, Zeilenbegrenzer (newline)
Begrenzer: ( ) [ ] ; . { }
Kommentare
Anweisungen
import-Anweisung
Klassendeklaration
Methode main
Objekt „out“
Kommentare werden im C++ - Stil eingefügt: beginnt mit //. C-Stil beginnt mit /* und endet
mit */. Schachtelung nicht erlaubt. Java-doc-Kommentare /** HTML bzw. XML-Text */.
© S. Meißner & A.Vogl
Seite 5
Softwaretechnik, Mitschrift 2. Semester
Generell gilt: Kommentare sind für die Dokumentation und die Lesbarkeit des Programms. Es
soll gut dokumentiert sein (20-30% der Zeilen für Kommentare). Kommentare werden durch
den Compiler entfernt. Aus Java-doc-Kommentaren werden HTML-Seiten erstellt.
Betrachten wir nun näher public static void main(String[] args):
public:
static:
void:
main:
String[]:
args:
Zugriffsmodifikator. Alle dürfen diese Methode aufrufen
Klassenzugehörigkeit
Rückgabewert
Methodenname
„Typ“ des Parameters
Name des Parameters
© S. Meißner & A.Vogl
Seite 6
Softwaretechnik, Mitschrift 2. Semester
2. Variablen, Typen und Operatoren
2.1 Variablen
Es gibt Variablen für unterschiedliche Typen. Wir unterscheiden dabei grundsätzlich
zwischen Referenztypen und primitiven Datentypen. Zu diesen gehören Typen gehören byte
(8 bit), short (16 bit), char (16 bit), int (32 bit) und long (64 bit), die Gleitkommatypen float
und double sowie boolean.
Im Allgemeinen werden Variablen wie folgt beschrieben:
Typ
Typ
int
int
Variablenname;
Variablenname = Wert;
array [ ] = null;
[ ] array = null;
//
//
//
//
normale Variablendefinition
Variablendefinition mit Wertzuweisung
Array – Deklaration
andere Schreibweise für Arrays
Der Zuweisungsoperator ist das = . Dabei gilt folgendes zu beachten:
Var = Wert;
Var = ´´Referenz´´;
String s;
s = ´´abc´´;
int i = 3;
byte b; int i;
b = i;
// Folgendes geht nicht:
// int ist zu groß für byte. Beachte:
// linke Seite muss Typkompatibel sein!
2.2 Der Typ boolean
Wir können mit boolean numerische Vergleiche durchführen mitteln ==, !=, >, <, >=, <=. Sie
liefern stets boolesche Werte true oder false.
Es sind folgende Operatoren mit boolean gebräuchlich:
&, &&
!
UND
NEGATION
|, ||
^
ODER
EXKLUSIVES ODER
Die Operatoren == und != liefern den booleschen Wert als Ergebnis. Bei primitiven Typen
wird deren Inhalt verglichen. Bei Referenztypen wird die Adresse verglichen. Beispiel:
String a = ´´abc´´;
String b = ´´abc´´;
if (a == b) { ... }
String c = ´´ab´´;
c += ´´c´´;
if (a == c) { ... }
© S. Meißner & A.Vogl
// gibt Fehler da Adresse a != b
// c = ´´abc´´, aber dennoch Fehler!
Seite 7
Softwaretechnik, Mitschrift 2. Semester
Wir betrachten folgende Wahrheitstabelle zur Verdeutlichung:
A
B
A && B
A || B
A ^ B
f
f
t
t
f
t
f
t
f
f
f
t
f
t
t
t
f
t
t
f
Folgendes gilt beim Programmieren zu beachten:
if ((args[0] != null) & (args[0].length() != 1))
/** oben werden beide Seiten ausgewertet, untenstehender Syntax ist
typisch: */
if ((args[0] != null) && (args[0].length() != 1))
Man kann die folgenden Operatoren auch anders schreiben:
if
if
if
if
(A || B) {do action ( );}
// entspricht:
(A) {do action ( );} else if (B) {do action ( );}
(A ^ B) { ... }
// entspricht:
(A) != (B) { ... }
2.3 Der Typ byte
byte verwaltet Ganzzahlen von –128 bis 127. Es wird mit 8 bit dargestellt. Wir können uns
das folgendermaßen vorstellen:
Vorzeichen
0
1
1
0
1
0
0
1
= + 64 + 32 + 8 + 1 = +105
Beim Arbeiten mit Variablen vom Typ byte gibt es allerhand zu beachten:
byte a = 5; byte b = 3;
byte c = a + b;
byte d = 0x80;
// Fehler: Implizite Typerweiterung
// Fehler: entspricht 128 > byte
Java arbeitet mit der impliziten Typerweiterung. Man spricht dabei von Integralpromotion.
Das Ergebnis ist vom Typ long, wenn einer der beiden Operanden ebenfalls vom Typ long ist.
Sonst ist das Ergebnis int. Daher gibt es oben eine Fehlermeldung. Soll das Ergebnis in einen
bestimmten Typ umgewandelt werden, muss gecastet werden.
Casting:
byte c = (byte) (a + b);
byte d = (byte) (0x80);
// Fehler: entspricht 128 > byte
Es gibt die unären Operatoren +, -, ~ (bitweises Komplement).
byte a = ...;
byte b = - a;
byte c = + b;
© S. Meißner & A.Vogl
// Fehler: Auch hier findet eine
// implizite Typerweiterung statt.
Seite 8
Softwaretechnik, Mitschrift 2. Semester
byte d = ~ c;
// Es muss gecastet werden!
Es gibt auch Operationen der Form ++a / --a (Präfix) und a++ / a-- (Postfix). Es findet dabei
erst die Inkrementierung statt, dann der Vergleich bzw. analog umgekehrt:
int x = 3; int y = 4;
int z1 = ++x;
int z2 = y++;
// z1 = 4, x = 4;
// z2 = 4, y = 5;
Bei Operationen werden häufig Rechnungen in der Form
variable = variable operator wert;
benutzt. Dies geht leichter in der Form
variable operator= wert;
Hierbei wird automatisch gecastet, d. h. die Form steht für
variable = (typ) (variable operator wert);
Beispiele:
for (byte b = 0; b<10; b++) { ... }
for (byte b = 0; b<10; b= b+1) { ... }
for (byte b = 0; b<10; b += 1) { ... }
// Funktioniert!
// Fehler: Casting fehlt!
// Funktioniert!
2.4 Besondere Operationen
Im Folgenden werden wir uns zunächst die Schiebeoperatoren >>, << und >>> ansehen.
Danach betrachten wir die Bitoperationen &, |, ^ genauer.
Schiebeoperator << x; schiebt alle Bits um x – Stellen nach links. Also:
int a = 2;
a = a << 1;
// a erhält den Wert 4
Man kann sich das folgendermaßen vorstellen:
0
0
0
0
0
0
1
0
<< 1
0
0
0
0
0
1
0
0
Was passiert im folgenden Code?
int a = 1; a = a << 32;
Integer hat 32 Bit, wobei die erste Stelle fürs Vorzeichen reserviert ist. Es kann also nur um
0...32 Bit (bei long: 0...63 Bit) geschoben werden. Die Ausgabe ist demnach 1.
Es findet eine Quasi – Modulo – Operation statt:
a = a << i ⇔ a = a << (i % 32);
bzw. für long:
a = a << i ⇔ a = a << (i % 64);
Wir schieben nun in byte:
byte b = 1; System.out.println (b << 10);
die Variable b wird in int konvertiert und erst dann werden die Bit geschoben. Das Ergebnis
ist also ein int! Man beachte außerdem:
byte b = 1; b = b <<1;
© S. Meißner & A.Vogl
// gibt Compilerfehler!
Seite 9
Softwaretechnik, Mitschrift 2. Semester
Schiebeoperator >> x; schiebt das Vorzeichenbit ein um x – Stellen nach rechts, wobei das
Vorzeichen erhalten bleibt. Also:
int a = -1;
a = a >> 1;
Man kann sich das folgendermaßen vorstellen:
1
0
0
0
0 ...
>> 2
1
1
1
0
0
...
Schiebeoperator >>> x; schiebt x 0 – Stellen von links aus ein und verrückt auch das
Vorzeichenbit. Also:
int a = 1;
a = a >>> 1;
Man kann sich das folgendermaßen vorstellen:
1
0
0
0
0
...
>>> 2
0
0
1
0
0
...
Zur impliziten Typerweiterung für byte, short, char: b = (byte) ((b & 0xFF) >> 1);
führt leicht zu Fehlern, daher arbeitet man besser mit Methoden. Etwa:
b = CshiftUtil.shiftRight (b,1);
public class CshiftUtil {
public static byte shiftRight (byte b, int n) {
return (byte) ((b & 0xFF) >> n); }
public static short shiftRight (short s, int n) {
return (short) ((s & 0xFF) >> n); }
}
Wir haben bereits die Vergleichsoperatoren &&, ||, ^ kennengelernt, die den Typ boolean
ergeben. Nun betrachten wir die Bitoperatoren &, | genauer. Diese sind ähnlich den
Vergleichsoperatoren, nur dass hier bitweise verglichen wird.
Zunächst einmal die grundsätzliche Verwendung. Mit & maskiert man und kann Bits
ausblenden. Häufig wird dies in Verbindung als >> bzw. >>> - Kombinationen verwendet. Um
Bits zu setzen, gebraucht man |, wobei häufig erst ausgeblendet / gelöscht wird und dann
gesetzt. Mit ^ wird die Differenz gefunden.
Im folgenden Programmbeispiel wird eine Zahl vom Typ byte eingelesen und anschließend
wird die binäre Darstellung ausgegeben. Dies geschieht mit Hilfe der Bitoperatoren:
public class CandDemo {
public static void convert (byte b) {
for (int i = 0; i <= 8; i++) {
if (b & sMaskArray [i] != 0)
System.out.print (1);
else
System.out.print (0); }
}
public static final byte sMaskArray []
= {(byte) 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}
© S. Meißner & A.Vogl
Seite 10
Softwaretechnik, Mitschrift 2. Semester
Was geschieht hier? Zunächst erstellen wir ein Array mit 8 Byte, die sMaskArray:
10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001
⇔
(byte)0x80
0x40
0x20
0x10
0x08
0x04
0x02
0x01
Jetzt sei b = -3. Dies entspricht dem binären Code
11111101.
Jetzt maskieren wir den Code mit der Stelle i im
Array entsprechend:
i = 0 => & 10000000
Das Ergebnis von 11111101 & 10000000 ist 10000000. Da dies ungleich 0 ist, wird eine 1
ausgegeben. Die Maskierung mit i = 6 wäre 11111101 & 00000010 und ergibt 00000000. Da
dies Ergebnis gleich 0 ist, wird eine 0 ausgegeben. Auf diese Weise erhalten wir schließlich
den richtigen Binärcode für –3, nämlich 11111101.
Wir haben gesehen, wie der Computer „addiert“. Sehen wir uns nun also noch einmal
zusammengefasst an, wie der Computer bitweise vergleicht:
a
b
a
a
a
=
=
&
|
^
01000101;
10010011;
b = 00000001;
b = 11010111;
b = 11010110;
// Vor dem Ergebnis stehen noch 24 Einsen,
// da in 32 int – Bit kobnvertiert wurde.
Zum Abschluss noch zu EXOR ein paar Beispiele:
int
int
a =
b =
a =
a
b
a
b
a
=
=
^
^
^
1;
2;
b;
a;
b;
//
//
//
//
//
entspricht
entspricht
entspricht
entspricht
entspricht
0...01
0...10
0...11
0...01, b ist also = 1
0...10, a ist also = 2
2.5 Gleitkommatypen
Zu den Gleitkommatypen gehören float (32bit, 7stellig) und double (64bit, 15stellig). Sie
werden für Vergleichsoperatoren genutzt. Um diese Typen umzuwandeln, müssen folgende
Methoden beachtet werden:
String valueOf (float)
String valueOf (double)
Man benutzt unäre Operatoren +, - oder arithmetische Operatoren +, -, *, /. Auch
Inkrementrechnungen ++, --, auch als Post- und Präfix, sind möglich. Hinzu kommen die
speziellen Werte +0.0, -0.0, +∞, -∞ (+ Infinity, - Infinity), sowie NaN (not a number, z. B. –
1, da dies keine reelle Zahl ist!):
Double.isNaN (double d)
Float.isNaN (float f)
© S. Meißner & A.Vogl
// Ausgabe boolean
Seite 11
Softwaretechnik, Mitschrift 2. Semester
Beispiele:
...
double d = -1.0;
d = Math.sqrt (d);
// squareroot (Quadratwurzel)
if (Double.isNaN (d)) {
System.out.println (“Wurzel ziehen nicht möglich”); }
...
System.out.println (1/0);
// java.lang.ArithmeticException
System.out.println (1.0/0); // Ausgabe: Infinity
Bei Ganzzahlen kommt es bei einer „durch 0” – Operation zu einer Exception. Bei
Gleitkommazahlen ist dies möglich als Infinity.
...
double a = 1.1;
if (3 * a == 3.3)
System.out.println (´´gleich´´);
else
System.out.println (´´ungleich´´);
Als Ausgabe wird ungleich erscheinen. Der Grund ist, dass der PC 1.1 + 1.1 + 1.1 rechnet
und dabei einen Rundungsfehler macht: 3.3000000000000003 und das ist ungleich 3.3! Auch
hier rechnet man besser mit Math – Methoden:
if ( 3 * a == 3.3) { ... }
// Fehler! Besser mit Methode:
public static final double EPSILON = 1.0e – 20;
if (Math.abs (x-y) < EPSILON)
// quasi gleich
{ ... }
2.6 Typumwandlung
Beispiele:
int i = System.in.read ( );
char c = (char) i;
// -1 für Dateiende
// explizite Typumwandlung
Implizite Typumwandlung:
evtl. Informationsverlust
byte
short
int
long
float
double
char
Beispiel:
byte b=1;
b += 1.6;
© S. Meißner & A.Vogl
// entspricht b = (byte) (b + 1.6)
Seite 12
Softwaretechnik, Mitschrift 2. Semester
Byte b wird in double umgewandelt, erst dann werden 1.6 addiert und durch abschneiden
zurück gecastet.
Jeder Ausdruck hat einen Wert. Was, wenn Typ S erwartet wird aber Typ T kommt?
Entweder Kompilierfehler:
int a = 1;
if (a) {...}
// boolean – Bedingung, aber a = int!
oder implizite Typumwandlung (elementare Typerweiterung, auch bei Referenzen):
a op = b;
b <<= 1;
String s = ´´abc´´;
Object o = s;
Typverkleinerungen „cast”. Beispiel:
(Typ)(Ausdruck);
int i;
byte b = (byte) i;
b = (byte) i+1;
b = (byte)(i+1);
// hier Kompilierfehler
// richtig
Was geschieht bei der Umwandlung nach String?
int i = 5;
String s;
s = i;
s = String.valueOf (i);
s = ´´´´ + i;
//
//
//
//
Fehler: i erst in Objekt umwandeln!
richtig
richtig, da String + i
also interner Aufruf von valueOf
String t;
Double d = new Double (1.0);
System.out.println (d);
// interner Aufruf toString
t = d;
// Fehler da unterschiedliche Typen
t = d.toString ();
// richtig
Konversionskontexte:
bei Zuweisungen (implizit):
• elementare Typvergrößerung
• „Vergröberung / Vergrößerung bei Referenzen”
elementare Typverkleinerungen wenn
• Ausdruck konstant
• Variablen nur vom Typ byte, short, char
• Wert des Ausdrucks liegt im Wertebereich der Variablen (daher byte b =
1; möglich!) => „Zuweisungskompatibel“
bei Methodenaufrufen:
© S. Meißner & A.Vogl
Seite 13
Softwaretechnik, Mitschrift 2. Semester
•
nur Vergrößerung:
public static void f (byte b) {…}
public static void f (float f) {…}
f (5);
// in int
f (0.0);
// double => Compilerfehler
f (1.0F);
// in float
2.6 String
Wir erzeugen einen String über Zeichenliterale
String s = ´´Java``;
oder über Konstruktoren:
char [] charArray = {´J´,´a´,´v´,´a´};
String s = new String (charArray);
Wir wollen nun Strings miteinander vergleichen.
byte b [] = {1, 2, 3, 4};
String t = new String (b);
String v = new String (t);
if (v == t) { ... };
// ASCII – Unicode!
// Vergleich möglich, da v, t auf das
// gleiche Objekt zeigen
Nun sehen wir uns einige String – Methoden an:
char charAt (int index);
int length ();
boolean equals (String other);
int compareTo (String other); // >0 wenn alphabetisch größer
// ==0 wenn gleich
// <0 sonst
public static String valueOf (byte) { ... }
int indexOf (char c)
// sucht Zeichen,
// -1 falls nicht vorhanden,
// sonst Ausgabe des 1. Index
Wir wollen nun überprüfen, ob eine Eingabe eine Zahl ist:
public static boolean isDigit (char c)
{ if (c >= ´0´&& c <= ´9´) return true;
else return false; }
// oder:
{ return (´´0123456789´´.indexOf ( c ) != -1); }
Wie fügt man zwei Variablen des Typs Strings zusammen?
String.concat (String other);
String a = ´´abc``; String b = ´´def´´;
String c = a.concat (b);
// oder kurz:
a + b;
void trim ();
// entfernt „überflüssige“ Zeichen, wie Leerstellen
© S. Meißner & A.Vogl
Seite 14
Softwaretechnik, Mitschrift 2. Semester
Im nächsten Beispiel soll eine Zeichenkette rückwärts wieder ausgegeben werden.
public static String createReverse (String s) {
String result = new String ();
for (int i = s.length()-1; i >= 0; i--) result +=(s.charAt(i)); }
Hier werden jedoch viele Objekte angelegt. Daher ist folgende Version ein besserer Syntax:
char tmpArray [] = new char [s.length()];
for (int i = s.length() –1, j = 0; i >= 0; i--, j++) {
tmpArray [j] = s.charAt (i); }
return (new String(tmpArray));
Damit sind wir bei den Arrays angelangt, die im folgenden Kapitel genauer untersucht werden
sollen.
2.7 Arrays
Arrays sind Java – Objekte. Sie werden dynamisch erzeugt und haben eine Referenz. Wir
definieren zunächst eindimensionale Arrays:
Type [] identifier;
Type identifier [];
int [] intArray;
System.out.println (intArray [0]); // Fehler: Nullpointer – Exception
identifier = new Type [size];
int Array = new int [3];
// reserviert drei Speicherplätze
Ein Array kann auch folgendermaßen deklariert werden:
int c [];
c = new int [] {2, 3, 4];
Bei Arrays mit Strings müssen zusätzliche Dinge beachtet werden:
String sArray [] = new String [3];
System.out.println (sArray [0]);
// gibt null aus
sArray [i];
sArray [0] = ´´a´´; sArray [1] = ´´b´´; sArray [2] = ´´c´´;
int aArray [] = {1, 2, 3};
byte bArray [] = {0, 1};
String sArray [] = {´´abc´´, ´´def´´, new string (bArray)};
sArray.length;
// als Attribut, Eigenschaft
Für den Index byte, short, char und int (nicht long!) gelten alle aufgeführten Eigenschaften für
Arrays. Bei Zuweisungen gilt folgendes:
int c [] = aArray;
c [0] = 3;
// ändert nun auch aArray!
System.out.println (aArray [0]);
final int aArray [] = {1, 2};
© S. Meißner & A.Vogl
Seite 15
Softwaretechnik, Mitschrift 2. Semester
aArray [0] = 5;
// final schützt nur Arrayname!
aArray = x;
// geht nicht wegen final!
// es geht auch:
int aArray [] = {1, 2, 3};
int bArray [] = {0, 1};
bArray = aArray;
Längenangaben sind immer ≥ 0. Man kann also auch Arrays der Länge 0 erstellen:
double d [] = new double [0];
Zugriff auf Arrays erlangt man mit dem Attribut length oder einem Indexoperator. Dabei
gilt, für einen illegalen Index int die ArrayIndexOutOfBoundsException.
int a [] = {1, 2, 3};
int b [];
b = a;
b [0] = 5;
System.out.println (a[0]);
// Ausgabe „5“
Nach dieser Methode zeigt die Variable b auf die gleiche Speicheradresse wie a. Wir wollen
nun aber ein Array kopieren, d. h. zwei Variablen zeigen auf zwei Speicheradressen gleichen
Inhalts. Dafür gibt es drei verschiedene Verfahren:
int a [] = {1, 2, 3};
// Möglichkeit 1: Lösung mit einer for - Schleife
b = new int [a.length];
for (int i = 0; i <= a.length; i++)
b [i] = a [i];
...
// Möglichkeit 2: Arrays sind Objekte und haben daher auch Methoden
b = (int[]) a.clone();
...
// Möglichkeit 3: die schnellste Methode vom Typ:
System.arraycopy (vonArray, vonIndex, nachArray, nachIndex, Anzahl);
// also
b = new int [a.length];
System.arraycopy (a, 0, b, 0, a.length);
Betrachten wir nun mehrdimensionale Arrays. Diese sind von folgendem Typ:
int a [] [];
a = new int [2] [3];
Ein zweidimensionales Array kann man sich wie folgt vorstellen:
a
Typ von a [0] ist int [], also z. B. a [0] [1];. Weitere Beispiele für mehrdimensionale
Arrays:
© S. Meißner & A.Vogl
Seite 16
Softwaretechnik, Mitschrift 2. Semester
double b []
double b []
b [0] = new
b [1] = new
int c [] []
int c [] []
[] = new double [2] [];
[] = new double [] [3];
// Fehler!
double [3];
double [10];
= { {1, 2, 3}, {4, 5}, {} };
= { {1, 2, 3}, {4, 5}, new int [20] };
Im letzten Beispiel zeigt das Array Integer c auf das Array der 1. Dimension, das auf drei
andere Arrays in der 2. Dimension zeigt, mit den jeweils entsprechenden Inhalten.
Betrachten wir ein Beispiel für das Arbeiten mit Arrays:
int a [] [] = new int [2] [];
for (int i = 0; i < a.length; i++) {
a [i] = new int [i + 1] }
int b [] [];
b = (int [] []) a.clone;
// wir haben nun das 1. Array geklont, es zeigt aber auf die gleiche
// Speicheradresse wie das Array a. Deswegen:
for (int i = 0; i <= a.length; i++) {
b [i] = (int []) a[i].clone []}
...
Im folgenden Beispiel geben wir eine Wahrheitstabelle aus:
public static void inc (boolean [] b) {
boolean c = true;
for (int i = b.length-1; i >=0 && c; i--) {
if (b [i] == true) {
b [i] = false;}
else {
b [i] = true;
c [i] = false; }
}
}
...
while b [0] == false {
print (b)
inc (b);
}
...
© S. Meißner & A.Vogl
Seite 17
Softwaretechnik, Mitschrift 2. Semester
3. Elementare Java - Anweisungen
3.1 Allgemeines
Die leere Anweisung besteht nur aus einem Semikolon:
for (int i = 1; i < 10; i++);
i = 1; System.out.println (´´hello´´);
for (int i = 1; i < 10; i++) { ; }
// entspricht:
// Anwendung als Warteschleife:
while (b) {;}
Wir haben schon diverse Ausdruck – Anweisungen kennen gelernt:
a = s;
i++;
--i;
methode (param1, ...) { ... }
klassenname.methode (...);
//
//
//
//
//
Zuweisung
Inkrement (Präfix)
Dekrement (Postfix)
Methodenaufruf mit Wertübergabe
z. B. System.out.println (...);
Mit new erzeugen wir ein neues Objekt. Beispiele:
new String ();
String a = new String (´´abc´´);
String b = new String (a);
Häufig stehen Anweisungen als Blockanweisung in geschweiften Klammern. Sehen wir uns
dazu die if – Anweisung an:
if (Bedingung) Anweisung;
if (Bedingung) { Anweisung };
if (Bedingung1) { Anweisung1 };
else { Anweisung2 };
3.2 Methoden
Java – Programme bestehen “weitgehend” aus Methoden. Methode ist eine Folge von
Anweisungen (Befehle). Anweisungen sind mit Semikolon abzuschließen (Ausnahme:
Blockanweisungen { ... } ).
© S. Meißner & A.Vogl
Seite 18
Softwaretechnik, Mitschrift 2. Semester
3.3 Statements
Man unterscheidet den empty statement ; oder { } und den block statement:
{
}
block statement
Genauer betrachtet sieht ein block statement wie folgt aus:
lokale Var, Deklaration, Statement
statement
Zu den Ausdrucksanweisungen (expression statements) gehören:
• Zuweisungen (assignments)
• De- / Inkrementierung (++ / --)
• Methodenaufrufe (method inrocation)
=> doIt ();
• Erzeugung von Objekten (class instance creation )
=> new String (´´abc´´);
3.4 IF – Anweisungen
Struktur:
if (Bedingung) {
Anweisung 1 }
else if (Bedingung) {
Anweisung 2 }
else {
Anweisung 3 }
Man kann einen Algorithmus wie folgt notieren:
PAP
(Programm – Ablauf – Plan)
Struktogramm
Ausdruck
Ausdruck
Anw. 1
© S. Meißner & A.Vogl
true
Anw. 2
false
Anw. 1
Anw. 2
Seite 19
Softwaretechnik, Mitschrift 2. Semester
Beispiel 1: Berechne aus 2 gegebenen Gleichungen x und y. Also: Wenn ax + by = c und für
dx + ey = f, dann ist x = (c * e – b * f) / nenner; y = (a * f – c * d) / nenner.
public static final double Espilon = 1.0 E –15;
public static double [] calc (double a, double b, double c, double d,
double e, double f) {
double nenner = a * e – b * d;
if (Math.abs(nenner) > Espilon) {
double sol [] = new double [2];
sol [0] = (c * e – b * f) / nenner;
sol [1] = (a * f – c * d) / nenner;
return sol;
}
else return null;
}
Beispiel 2: Berechne den Absolut – Betrag einer Zahl x.
public static double abs (double x) {
if (x >= 0) return x;
else return –x;
}
Beispiel 3: Erstelle eine Punkte – Note – Liste.
if (points > 80) grade = 1;
else if (points > 60) grade = 2;
else if (points > 40) grade = 3;
else if (points > 20) grade = 4;
else grade = 5;
Beispiel 4: Berechne die Fakultät der Zahl n!.
public static long fakultaet (int n) {
if (n == 0)
return 1;
else
return x * fakultaet (n – 1);
}
Das obere Beispiel ist eine rekursive Funktion. Die Berechnung für z. B. fakultaet (4) ist
4 * fak (3) = 4 * 3 * fak (2) = 4 * 3 * 2 * fak (1) = 4 * 3 * 2 * 1 * fak (0) = 4 * 3 * 2 * 1* 1
© S. Meißner & A.Vogl
Seite 20
Softwaretechnik, Mitschrift 2. Semester
3.5 Switch – Anweisung
Betrachten wir die Struktur der Switch – Anweisung als PAP:
Auswahl
Anw1
Anw1
Anw1
Anw1
Die Switch – Anweisung funktioniert nur mit byte, short, char und int:
switch (Ausdruck) {
case fall1: Anw1;
case fall2: Anw2;
...
default: Defaultanweisung;
}
Die Konstanten fall1, fall2, ... müssen zuweisungskompatibel zum Ausdruck sein. Keine der
zwei case – Markierer dürfen den gleichen Wert haben. Default darf auch nur einmal
vorkommen!
int a;
switch (a)
case
case
...
case
{
0.0: ...;
1: ...;
// nicht erlaubt!
1: ...;
// nicht erlaubt!
}
Beispiel: Wir erstellen eine Methode für ein Kalenderprogramm.
public static int calcDays (int theMonth, boolean isLeapYear) {
int days = 31;
switch (theMonth) {
case 4:
case 6:
case 9:
case 11:
days = 30; break;
case 2:
days = (isLeapYear ? 29 : 28); break;
default: days = 31;
}
return days;
}
© S. Meißner & A.Vogl
Seite 21
Softwaretechnik, Mitschrift 2. Semester
Beispiel: Für eine Zahl geben wir einen Text aus.
String txt;
switch (zahl)
case 0:
...
case 9:
default
}
{
txt = ´´null´´; break;
txt = ´´nein´´; break;
txt = ´´Fehler!´´;
Besser zu handhaben ist in diesem Fall eine IF – Array – Kombination:
final String txtArray [] = {´´null´´, ´´eins´´, ...};
if (zahl >= 0 && zahl <= 0)
txt = txtArray [zahl];
else txt = ´´fehler´´;
3.6 Schleifen
Zunächst betrachten wir die do – while – bzw. while – Schleife. Diese beiden Schleifentypen
unterscheiden sich insofern, als dass die do – while – schleife auf jeden Fall einmal ausgeführt
wird. Syntax:
while (Bed) {
Anweisung (dabei wird Bed. geändert) }
do {
Anweisung }
while (Bed);
...
while (x < 10) x++;
while (x < 10) {x++}
// identisch!
...
int querSumme = 0;
while (x != 0) {
querSumme += (x % 10);
x /= 10; }
Sehen wir uns nun die for – schleife an.
for
(
ForInit
;
Expr
;
ForUpdate
)
Statement
Die „leere“ for – Schleife entspricht einer Endlosschleife while (true) { ... }:
for ( ; ; ) { ... }
Wir sehen uns nun noch genauer die ForInit an:
,
StatementExpression
© S. Meißner & A.Vogl
Seite 22
Softwaretechnik, Mitschrift 2. Semester
LocalVariableDeclaration
Beispiele:
for (int i = 0, j, float=0.0; ; ) { ... }
for (a+b; x <= 10; x++)
// oben: Fehler => keine Ausdrucksanweisung!
int b;
for (int a = 5, b = 3; ; ) { ... }
// oben: Fehler => Deklaration und Ausdruck nicht erlaubt!
for ( ; x != 0; x /= 10) { querSumme += (x % 10); }
Wir sehen uns nun die einzelnen Notationen an.
while
do – while
for
Schleife
Ausdruck
Schleife
Ausdruck
AW=...SW=...EW=...
Anweisung
Anweisung
Anweisung
Ende
Schleife
Ausdruck,
Ende Schleife
Ende
Schleife
Ausdruck
Anweisung
Anweisung
Schleife
for (start,end,schritt)
Ausdruck
Anweisung
Beispiel:
static final double Epsilon = 1.0 e 10;
public static double sqrt (double x) {
double links = 0;
double rechts = x;
while (rechts – links > Epsilon) {
double tmp = (rechts + links) / 2;
if (tmp * tmp > x)
rechts = tmp;
else
links = tmp;
}
return links;
}
© S. Meißner & A.Vogl
Seite 23
Softwaretechnik, Mitschrift 2. Semester
3.7 break- und continue – Anweisungen
Wir sehen uns die Struktur an:
break
;
identifier
continue
;
identifier
Der „identifier“ wird auch als Sprungmarke bezeichnet. Eine mit Label versehene Anweisung
sollte vermieden werden, weshalb hier auch nicht näher darauf eingegangen werden sollte.
3.8 return – Anweisung
return
;
Expression
© S. Meißner & A.Vogl
Seite 24
Softwaretechnik, Mitschrift 2. Semester
4. Klassen und Objekte in Java
4.1 Objekte
Ein Objekt wird beschrieben durch Zustand und Verhalten. Der Zustand wird bestimmt durch
Daten / Attribute. Verhalten wird bestimmt durch Methoden.
public class CPoint {
private int mx; private int my;
public CPrint () { mx = my = 0; }
public void setx (int thex) { mx = thex; }
public void sety (int they) { my = they; }
public int get x () { return mx; }
public int gety () { return my; }
public void mor (int dx, int dy) {
mx += dx; my += dy; }
public String toString () {
return ´´(´´ + mx + ´´,´´ + my + ´´)´´; }
}
Objekte besitzen also Daten / Attribute / Zustände, ein Verhalten sowie eine Identität.
4.2 Klassen
Klassen beschreiben Objekte. Sie werden auch „abstrakte Datentypen“ genannt, da mit ihnen
Objekte erzeugt werden.
Wir wollen zunächst ein Rechteck konstruieren. Dafür sind zwei Objekte ausreichend, da wir
nur den linken oberen und den rechten unteren Punkt mithilfe zweier Variablen erzeugen
müssen. Der Syntax könnte also wie folgt aussehen:
public class CRectangle {
private CPoint mUpperLeft;
private CPoint mLowerRight;
public CRectangle () {
mUpperLeft = new CPoint ();
mLowerRight = new CPoint ();
}
}
Wir wollen in einem großen Beispiel das Zusammenspiel von Klassen und Objekten
verstehen. Dazu werden wir eine Klasse für rationale Zahlen erstellen:
• wir benötigen int zaehler; und int nenner;
• ein Objekt „erzeugt / initiallisiert“ wird benötigt
• Addition, Multiplikation, Subtraktion und Division sollen möglich sein
• Vergleiche von rationalen Zahlen werden durchgeführt
• Ausgabe mittels der Methode toString
© S. Meißner & A.Vogl
Seite 25
Softwaretechnik, Mitschrift 2. Semester
public class CRational extends java.lang.Object
// 1
private int zaehler;
private int nenner;
public CRational () {
// 2
zaehler = 0;
nenner = 1;
}
public CRational (int z, int nenner) {
// 3
zaehler = z;
this.nenner = nenner;
// 4
normalize ();
// 5
}
public String toString () {
return zaehler + ´´/´´+ nenner;
}
private void normalize () {
boolean isNegative;
if (zaehler < 0) {
isNegative = true;
zaehler = - zahler; }
if (nenner < 0) {
isNegative = !isNegative
nenner = - nenner; }
int ggT = ggT (zaehler, nenner);
zaehler /= ggT;
nenner /= ggT;
if (isNegative)
zaehler = - zaehler;
}
public static int ggT (int a, int b) {
// 6
int tmp;
while (b != 0) {
tmp = a % b;
a = b;
b = tmp;
}
return a;
}
public void add (CRational other) {
// 7
this = add (this other);
}
public static CRational add (CRational r, CRational s) { // 8
int z = r.zaehler * s.nenner + r.nenner * s.zaehler;
int n = r.nenner * s.nenner;
return new CRational (z, n);
}
...
// 9
public int compareTo (Crational other) {
return sub (this, other).zaehler;
// 10
}
public boolean equals (Object other) {
if ((other instanceOf (CRational)) == false)
return false;
return compareTo ((CRational).other) == 0;
// 11
}
}
public class CtestRational {
public static void main (String args []) {
...
}
}
© S. Meißner & A.Vogl
// 12
Seite 26
Softwaretechnik, Mitschrift 2. Semester
Bemerkungen:
1.
Diese Klasse einzubinden ist überflüssig, da sie quasi die „Mutterklasse“ aller
Klassen ist.
2. Dieser Konstruktor hat den gleichen Namen wie die Klasse, da dies die Methode ist,
mit der wir das Objekt erzeugen. Sie wird aufgerufen, wenn keine Variablen
übergeben werden, vom Typ: CRational r = new CRational ();
3. Hier gilt das gleiche wie bei 2). Nur wird dieser Konstruktor aufgerufen, wenn die
Syntax vom Typ ist: r = new CRational (-5, 7);
4.
this deutet Java an, dass es sich um die Variable nenner aus dem Objekt private
nenner; handelt.
5.
Diese Methode werden wir noch schreiben, um den ggT für die rationale Zahl zu
finden.
6.
Es handelt sich hier um eine „statische“ Methode, d. h. sie ist an ein Objekt
gebunden, da sie nur hier „interessant“ bzw. relevant ist.
7.
Der Aufruf muss vom Typ sein: r.add (t);
8.
Dieser Aufruf ist vom Typ: u = add (r, s);
9.
Analog werden Methoden für Subtraktion, Multiplikation und Addition erstellt.
10. Es handelt sich bei sub (this, other) um ein „anonymes Objekt“.
11. Diese ungewöhnlich wirkende Form ist lediglich ein cast – Operator in CRational,
welches sich ebenso verhält wie beim Casting nach int.
12. Um unsere Klasse zu überprüfen, ob sie so funktioniert, wie wir es uns wünschen,
schreiben wir eine Testklasse, die lediglich eine main – Methode enthält und auf die
Klasse zugreift und mit ihr arbeitet.
© S. Meißner & A.Vogl
Seite 27
Softwaretechnik, Mitschrift 2. Semester
4.3 Deklarationen
Nun wollen wir uns mit Klassen näher beschäftigen. Klassen können entsprechend ihres
Nutzens modifiziert werden:
public
class
private
•
•
•
•
protected
final
abstract
Identifier
Body
public ist eine öffentliche Klasse
private wird nur in einer Klasse verwendet
protected wird nur in einer Klasse verwendet
final kann nicht vererbt werden
Sind Klassen in einem package zusammengefasst, sind
die einzelnen Klassen für alle immer sichtbar.
Der Body steht in geschweiften Klammern. Diese können entweder leer stehen oder mit
Inhalten besetzt sein:
{
}
Method Declaration
Field Declaration
class Declaration
Stratic Initializer
Für die Variablen gelten verschiedene Zugriffsmodifikationen. Insgesamt sind es die acht
Methoden public, private, protected, final, static, volatile, tranisent oder ohne.
Außerdem gibt es noch native, abstract und synchronized.
Wir wollen nun ein Stack für Integer anlegen:
CStack
•
•
int mStack [ ]
int mTopIndex
<< constructor >>
push (int)
•
•
•
© S. Meißner & A.Vogl
pop ( ): int
peek ( ): int
isEmpty ( ): boolean
Seite 28
Softwaretechnik, Mitschrift 2. Semester
public class CStack {
private int mStack [];
private int mTopIndex;
public CStack (int theSize) {
mStack = new int [theSize];
mTopIndex = -1;
}
public void push (int val) {
mTopIndex ++;
mStack [mTopIndex] = val;
}
public int pop () {
int val = mStack [mTopIndex];
mTopIndex --;
return val;
}
public int peek () {
return mStack [mTopIndex];
}
public boolean isEmpty () {
return (mTopIndex == -1);
}
}
public static String reverse (String txt) {
CStack stack = new CStack (txt.length);
for (int i = 0; i < txt.length(); i++)
stack push (txt.charAt (i));
String buffer b = new String Buffer ();
while (stack.isEmpty() == false) {
char d = (char) stack.pop ();
b.append (d);
}
return b.toString ();
}
Variablen können also auch nicht nur verschiedenen Typen haben, sondern zusätzlich
deklariert sein:
Type
Var Declarations
;
private
public
protected
final
static
volatile
© S. Meißner & A.Vogl
private int a;
int b = 5;
public int c [] = new int [6];
private long a [] = {1, 2, 3};
private JButton buttonArray [] {
new JButton (´´button1´´);
new Jbutton (´´button2´´);
}
Seite 29
Softwaretechnik, Mitschrift 2. Semester
4.4 Methoden
Eine Methode hat einen Block für die Implementierung und eine Signatur (bestehend aus
Name der Methode und Anzahl und Typen der Parameter (eventuell auch mit Typ des
Rückgabewerts)):
Typ
(
identifier
)
Formal
Parameter
List
void
public
protected
private
static
final
;
}
abstract
{
throws
Block Statements
synchronized
native
•
•
•
•
void wird benutzt, wenn kein Rückgabetyp erwartet wird.
Die Klammer () kann sowohl leer bleiben als auch mit einem FormalParameterList
besetzt werden.
static signalisiert eine Methode für eine Klasse, nicht für ein Objekt.
native bedeutet, dass das Programm nicht in Java geschrieben ist.
Sehen wir uns nun throws genauer an:
throws
ClassType
,
© S. Meißner & A.Vogl
Seite 30
Softwaretechnik, Mitschrift 2. Semester
Methoden können überladen werden, d. h. verschiedene Methoden haben gleiche Namen. Ein
Beispiel dafür:
public class CRectangel {
public boolean contains (CPoint p)
{ ... }
public boolean contain (float x, float y)
{ ... }
}
Im Folgenden Beispiel entsteht ein Fehler:
void move (int x, int y)
{ ... }
static void move (int x, int y)
{ ... }
// Methode für ein Objekt
// Methode für eine Klasse
Der Compiler kann die Signaturen nicht unterscheiden. Auch nimmt der Compiler keine
Rücksicht auf den Rückgabewert, weshalb auch im Folgenden ein Fehler entsteht:
int move (int x, int y)
{ ... }
Das folgende Programm enthält ebenfalls einige Fehler:
public class CTest {
void doIt (byte a, int b) { ... }
void doIt (int a, byte b) { ... }
public static void main (String args []) {
byte a, b;
...
doIt (a, b)
// Fehler, da kein Objekt vorhanden ist
CTest obj = new Ctest ();
obj.doIt (a, b); // Fehler, da nicht eindeutig
obj.doIt (5, 6); // impl. Typerweiterung auf 2 Integer
obj.doIt (1, b); // Aufruf 2. Methode, da int, byte
© S. Meißner & A.Vogl
Seite 31
Softwaretechnik, Mitschrift 2. Semester
4.5 Konstruktoren
Konstrukturen werden benötigt, um Objekte zu initialisieren. Der Name des Konstruktors ist
identisch zum Klassennamen und hat keinen Rückgabetyp.
Wenn kein Kontrsuktor deklariert wurde, fügt der Java – Compiler einen
„Standardkonstruktor“ hinzu. Im Folgenden ein Vergleich ein und desselben Quellcodes – vor
und nach der Compilerbearbeitung:
public class Ccircle {
private double mX;
private double mY;
}
public String toString () {
return mX, my;
}
import java.lang.*;
public class Ccircle
extends java.lang.Object {
private double mX;
private double mY;
public CCircle () {
super ();
}
public String toString () {
return mX, my;
}
}
Im Übrigen ist hier die Ausgabe 0.0 0.0. Ein weiteres Beispiel:
public class CCircle {
private double mX, mY;
public void CCircle () {
// Fehler, da wegen void Methode
mX = mY = 0;
}
public CCircle CCircle () {
mX += 1;
mY += 1;
return this;
}
public String toString () {
return mX, mY;
}
public CCircle (double x, double y) {
mX = x;
mY = y;
}
public static void main (String args []) {
CCircle c = new CCircle ();
System.out.println (new CCircle().CCircle());
}
}
Für den Konstruktor wird new benötigt. Dieses legt Speicher an, füllt diesen zunächst mit „0“
und ruft den Konstruktor auf. Man kann es daher auch „Initialisierer“ nennen:
public class CTest {
private JButton mButton = new JButton (´´hello´´);
public CTest ( ... ) {
mButton.setBackground (Color.red);
}
}
© S. Meißner & A.Vogl
Seite 32
Softwaretechnik, Mitschrift 2. Semester
4.6 Schlüsselwort this
Objekte haben auch „Identitäten“ (also Vergleichsreferenzen, Adressen, u. ä.). Doch
manchmal ist das Problem, welches Objekt vorliegt.
private int mX;
public void set (int mX) {
this.mX = mX;
}
public void otherMethod () {
...
this.set (5);
...
}
this ist nur bei Konstruktoren erlaubt. Es ist quasi eine Referenz zu dem Objekt selbst. Noch
ein Beispiel:
public class CTest {
public CTest () {
...
this (0, 0);
...
}
public CTest (int a, int b) {
...
this ();
...
}
Die beiden Methoden rufen sich gegenseitig auf und erzeugen somit eine Endlosschleife!
© S. Meißner & A.Vogl
Seite 33
Softwaretechnik, Mitschrift 2. Semester
4.7 Gültigkeitsbereich
Der Gültigkeitsbereich legt fest, in welchem Codeabschnitt die Variablen verwendet werden.
Dabei unterscheidet man:
1. formaler Parameter: Die Variable wird nur in der entsprechenden Methode benutzt.
void doIt (int a)
{ ... }
2. lokale Variable: Die Variable ist nur in dem Block gültig, wo sie definiert wurde.
3. Attribute: Attribute haben ihre Gültigkeit in der Klasse mit Ausnahmen von
Klassenmethoden. Dazu zwei Beispiel:
public class CClass {
int x, y;
public static void main (String args []) {
x = 1;
// Fehler!
CClass c;
c.x = 1;
// Funktioniert!
}}
public class CScopeDemo {
static int sGlobal = 0;
int mVar = 10;
void print1 () {
int mVar = 20;
int sGlobal = 1;
System.out.println (mVar + sGlobal +
this.mVar + CscopeDemo.sGlobal);
}
void print2 () {
System.out.println (mVar + sGlobal);
}
}
Im letzten Beispiel wäre die Ausgabe für print1 20 1 10 0 und für print2 10 0. Auf der
nächsten Seite folgt ein letzten Beispiel. Es besteht aus zwei Teilen, wobei der zweite Teil
identisch mit dem ersten ist, nur wurden die Variablen umbenannt, was, wie man sieht,
deutlich der Übersichtlichkeit dient.
© S. Meißner & A.Vogl
Seite 34
Softwaretechnik, Mitschrift 2. Semester
class Point {
int x, y;
}
class Test {
static Point Point (int x, int y) {
Point p = new Point ();
p.x = x;
p.y = y;
return p;
}
public static void main (String args []){
int Point;
Point pa [] = new Point [2];
for (Point = 0; Point < 2; Point ++) {
pa [Point] = new Point ();
pa [Point].x = pa [Point].y = Point;
}
System.out.println (pa [0].x + ´´ ´´ + pa [0].y);
System.out.println (pa [1].x + ´´ ´´ + pa [1].y);
Point p = Point (3, 4);
System.out.println (p.x + ´´ ´´ + p.y);
}
}
Die Ausgabe ist in der ersten Zeile 0 0, in der zweiten Zeile 1 1 und schließlich 3 4. Warum
das so ist wird deutlich, wenn wir die Variablen umbenennen:
class Point {
int x, y;
}
class Test {
static Point f (int x, int y) {
Point p = new Point ();
p.x = x;
p.y = y;
return p;
}
public static void main (String args []){
int c;
Point pa [] = new Point [2];
for (i = 0; i < 2; i ++) {
pa [i] = new Point ();
pa [i].x = pa [i].y = i;
}
System.out.println (pa [0].x + ´´ ´´ + pa [0].y);
System.out.println (pa [1].x + ´´ ´´ + pa [1].y);
Point p = f (3, 4);
System.out.println (p.x + ´´ ´´ + p.y);
}
}
© S. Meißner & A.Vogl
Seite 35
Softwaretechnik, Mitschrift 2. Semester
4.7 Methodenaufrufe und Parameterübergabe
Wir sehen uns die Parameterübergabe an einigen Beispiel an. Im ersten Beispiel wird die
Variable int a; unerlaubterweise überdeckt:
void print (int a, String s) {
int a;
...
}
...
print (5, ´´abc´´);
...
Im zweiten Beispiel werden die Variablen in der Methode swap vertauscht, wegen des
Parameters sind sie im Anschluss jedoch wieder „normal“:
int a, b;
public void swap (int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
...
a = 5; b = 7;
swap (a, b);
...
Nun legen wir Werte in die Onjekte b1 und b2 ab – die Vertauschung findet dauerhaft statt.
public void swap (JButton b1, JButton b2) {
JButton tmp = b1;
b1 = b2;
b2 = tmp;
}
4.8 Objektfreigabe
Wir legen ein Objekt an und weisen diesem keinen Wert (null) zu:
JButton b1 = new JButton(); ... b1 = null;
Hier wird der sogenannte Garbage Collector aktiv, der „überflüssige“ Daten löscht.
protected void finalize () throws Throwable = null;
System.gc ();
// Hinweis für den Garbage Collector!
Die finalize – Methode wird aufgerufen, bevor das Objekt freigegeben wird. Nach dem
beenden des Programms werden alle Ressourcen freigegeben. Nach dem Aufruf von
finalize wird erneut überprüft, ob das Objekt referenziert wird. Falls nicht, wird es
freigegeben. Achtung: Der Garbage Collector ist vorsichtig einzusetzen!
© S. Meißner & A.Vogl
Seite 36
Herunterladen