3
von
Laura Lemay
Am 1. und 2. Tag haben Sie allgemeine Dinge über die Java-Programmierung gelernt was ein Java-Programm ist, wie ein ausführbares Applet aussieht, wie einfache Klassen angelegt werden und was es mit der objektorientierten Programmierung auf sich hat. Den Rest dieser Woche lernen Sie Einzelheiten und befassen sich mit spezifischen Aspekten der Java-Sprache.
Heute definieren Sie keine Klassen oder Objekte und machen sich auch keine Gedanken, wie diese innerhalb eines Java-Programms miteinander kommunizieren müssen. Statt dessen befassen Sie sich mit einfachen Java-Anweisungen. Dies sind die Grundlagen für die Definition einer Methode, wie z.B. main().
Sie lernen heute folgendes:
Anweisungen sind in Java einfach und bilden jeweils eine einzelne Java-Operation. Nachfolgend Beispiele von einfachen Java-Anweisungen:
int i = 1;
import java.awt.Font;
System.out.println("This motorcycle is a "+ color + " " + make);
m.engineState = true;
Anweisungen geben manchmal Werte zurück, z.B. wenn Sie zwei Zahlen addieren oder prüfen, ob ein Wert einem anderen entspricht. Diese Arten von Anweisungen nennt man Ausdrücke. Diese lernen Sie noch in der heutigen Lektion.
Wie in C sind Leerzeichen auch in Java-Anweisungen unwichtig. Eine Anweisung kann auf einer einzelnen oder auf mehreren Zeilen stehen. Für den Java-Compiler hat das keine Bedeutung. Wichtig bei Java-Anweisungen ist, daß jede mit einem Semikolon (;) endet. Vergessen Sie ein Semikolon, wird Ihr Java-Programm nicht kompiliert.
In Java gibt es auch Mischanweisungen bzw. Blöcke, die irgendwo in einer Anweisung stehen können. Blockanweisungen werden zwischen geschweiften Klammern ({}) gesetzt. Sie lernen am 5. Tag mehr über Blöcke.
Variablen sind Stellen im Speicher, in denen Werte gespeichert werden können. Jede hat einen Namen, einen Typ und einen Wert. Bevor Sie eine Variable benutzen können, müssen Sie sie deklarieren. Danach können Sie ihr Werte zuweisen. (Sie lernen in dieser Lektion noch, daß Sie eine Variable auch gleichzeitig deklarieren und ihr einen Wert zuweisen können.)
Java kennt drei Arten von Variablen: Instanzvariablen, Klassenvariablen und lokale Variablen.
Wie Sie gestern schon gelernt haben, werden Instanzvariablen zum Definieren von Attributen oder des Zustands eines bestimmten Objekts benutzt. Klassenvariablen sind mit Instanzvariablen vergleichbar, außer, daß ihre Werte auf alle Instanzen der jeweiligen Klasse (und die Klasse selbst) zutreffen, also nicht für jedes Objekt einen anderen Wert haben.
Lokale Variablen werden innerhalb von Methodendefinitionen deklariert und benutzt, z.B. für Indexzähler in Schleifen, als temporäre Variablen oder zum Aufnehmen von Werten, die Sie nur innerhalb einer Methodendefinition brauchen. Sie können auch in Blöcken benutzt werden, was Sie in Lektion 5 lernen. Nach der Ausführung der Methode (oder des Blocks) hört die Variablendefinition und ihr Wert auf zu existieren. Sie benutzen lokale Variablen zum Speichern von Informationen, die in einer einzigen Methode benötigt werden, und Instanzvariablen zum Speichern von Informationen, die in mehreren Methoden eines Objekts benutzt werden.
Obwohl alle drei Variablenarten auf die gleiche Weise deklariert werden, unterscheidet sich der Zugriff auf Klassen- und Instanzvariablen und deren Zuweisung geringfügig von lokalen Variablen. Heute konzentrieren wir uns auf Variablen in Methodendefinitionen. Morgen lernen Sie den Umgang mit Instanz- und Klassenvariablen.
Um eine Variable in einem Java-Programm nutzen zu können, muß sie zuerst deklariert werden. Die Deklaration von Variablen besteht aus einem Typ und einem Namen:
int myAge;
String myName;
boolean isTired;
Variablendefinitionen können irgendwo in einer Methodendefinition stehen (d.h. überall, wo eine Java-Anweisung stehen kann). Üblicherweise werden sie aber am Anfang der Definition deklariert:
public static void main ( String args[] )
{
int count;
String title;
boolean isAsleep;
...
}
Sie können Variablennamen gleichen Typs auf einer Zeile verketten:
int x, y, z;
String firstName, LastName;
Ferner können Sie jeder Variablen bei der Deklaration einen Anfangswert zuweisen:
int myAge, mySize, numShoes = 28;
String myName = "Laura";
boolean isTired = true;
int a = 4, b = 5, c = 6;
Stehen in einer Zeile mit nur einer Initialisierungsanweisung mehrere Variablen (wie im ersten der obigen Beispiele), trifft der Anfangswert nur auf die Variable mit der Initialisierungsanweisung zu. Sie können einzelne Variablen (mit oder ohne Initialisierung) in der gleichen Zeile mit Kommas gruppieren, wie im letzten Beispiel oben.
Lokale Variablen müssen Werte haben, bevor sie benutzt werden können (Ihr Java-Programm wird nicht kompiliert, wenn es eine lokale Variable ohne zugewiesenen Wert enthält). Aus diesem Grund müssen lokalen Variablen immer Anfangswerte zugewiesen werden. Diese Einschränkung trifft auf die Deklaration von Instanz- und Klassenvariablen nicht zu. Ihr Anfangswert hängt vom Variablentyp ab: null für Klasseninstanzen, 0 für numerische Variablen, '\0' für Zeichen und false für boolesche Variablen.
In Java können Variablennamen mit einem Buchstaben, einem Unterstrich (_) oder einem Dollarzeichen ($) beginnen. Sie dürfen nicht mit einer Zahl beginnen. Nach dem ersten Zeichen kann ein Variablenname jeden Buchstaben und jede Zahl enthalten. Symbole wie %, *, @ usw. sind in Java meist für Operatoren reserviert und sollten deshalb in Variablennamen nicht verwendet werden.
Darüber hinaus benutzt die Java-Sprache den Unicode-Zeichensatz. Unicode ist eine Zeichensatzdefinition, die nicht nur die Zeichen des ASCII-Zeichensatzes, sondern auch mehrere Tausend andere Zeichen zur Darstellung der meisten Landessprachen bietet. Das bedeutet, daß Sie akzentuierte Zeichen und andere Sonderzeichen in Variablennamen benutzen können, sofern ihre Unicode-Zeichennummer über 00C0 liegt.
In Java wird Groß- und Kleinschreibung beachtet, was bedeutet, daß Java einen Unterschied zwischen großgeschriebenen und kleingeschriebenen Buchstaben macht. Das heißt, daß die Variable X nicht gleich x und rose nicht Rose oder ROSE ist. Denken Sie daran, wenn Sie Ihre eigenen Java-Programme schreiben oder Java-Code lesen, den andere Leute geschrieben haben.
Java-Variablen haben grundsätzlich aussagefähige Namen, die oft aus mehreren zusammengesetzten Wörtern bestehen. Das erste Wort ist klein geschrieben, während alle ohne Leerzeichen folgenden Wörter mit großem Anfangsbuchstaben geschrieben werden:
Button theButton;
long reallyBigNumber;
boolean currentWeatherStateOfPlanetXShortVersion;
Zusätzlich zum Variablennamen muß jede Variablendeklaration einen Typ haben, der bestimmt, welche Werte die Variable annehmen kann. Der Variablentyp kann
sein. Sie lernen am 5. Tag, wie Array-Variablen deklariert und benutzt werden. In dieser Lektion konzentrieren wir uns auf primitive und Klassentypen.
Die acht primitiven Datentypen liefern die üblichen Typen für Ganzzahlen, Gleitpunktzahlen, Zeichen und boolesche Werte (true oder false). Man nennt sie primitiv, weil sie im System integriert und keine eigentlichen Objekte sind. Deshalb ist ihre Verwendung effizienter. Beachten Sie, daß diese Datentypen maschinenunabhängig sind, was bedeutet, daß ihre Größe und Merkmale in allen Ihren Java-Programmen konsistent sind.
In Java gibt es vier Ganzzahlentypen mit je einem anderen Wertbereich (siehe Tabelle 3.1). Alle können entweder positive oder negative Zahlen aufnehmen. Welchen Typ Sie für Ihre Variablen wählen, hängt vom Wertbereich ab, den eine Variable aufnehmen soll. Wird ein Wert zu groß für den Variablentyp, wird er abgeschnitten.
Typ |
Größe |
Bereich |
Byte |
8 Bit |
128 bis 127 |
Short |
16 Bit |
32.768 bis 32.767 |
Ganzzahl (int) |
32 Bit |
2.147.483.648 bis 2.147.483.647 |
Long |
64 Bit |
9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807 |
Gleitpunktzahlen werden für Zahlen mit einem Dezimalteil benutzt. In Java entsprechen die Gleitpunktzahlen IEEE 754 (einer internationalen Norm zur Definition von Gleitpunktzahlen und Arithmetik). Ferner gibt es zwei Gleitpunkttypen: float (32 Bit, einfache Genauigkeit) und double (64 Bit, doppelte Genauigkeit).
Der Typ char wird für einzelne Zeichen benutzt. Da Java den Unicode-Zeichensatz verwendet, hat der Typ char eine Genauigkeit von 16 Bit und ist vorzeichenlos.
Der Typ boolean kann den Wert true oder false haben. Im Gegensatz zu anderen C-ähnlichen Sprachen ist boolean keine Zahl und kann auch nicht als solche behandelt werden. Alle Tests von booleschen Variablen sollten auf true oder false prüfen.
Alle primitiven Typen werden in Java kleingeschrieben. Achten Sie darauf, wenn Sie sie in Ihren Programmen verwenden, weil es auch Klassen mit den gleichen Namen (aber einem großen Anfangsbuchstaben) gibt, die ein anderes Verhalten aufweisen. So unterscheidet sich beispielsweise der primitive Typ boolean von der Klasse Boolean. Am 4. Tag lernen Sie mehr über diese speziellen Klassen und wofür sie benutzt werden.
Zusätzlich zu den acht grundlegenden Datentypen können Variablen in Java auch so deklariert werden, daß sie eine Instanz einer bestimmten Klasse aufnehmen:
String LastName;
Font basicFont;
OvalShape myOval;
Jede dieser Variablen kann nur Instanzen der jeweiligen benannten Klasse oder einer ihrer Unterklassen aufnehmen. Das ist nützlich, wenn Sie eine Variable erstellen möchten, um verschiedene Instanzen zusammenhängender Klassen aufzunehmen. Angenommen, Sie haben eine Reihe von Klassen für Früchte Apfel, Birne, Erdbeere usw. die alle von der allgemeinen Klasse Frucht erben. Wenn Sie eine Variable vom Typ Frucht deklarieren, kann diese Variable Instanzen jeder Frucht-Klasse der Oberklasse Frucht aufnehmen. Die Deklaration einer Variablen vom Typ Object bedeutet, daß diese Variable jedes beliebige Objekt aufnehmen kann.
Nachdem Sie eine Variable deklariert haben, können Sie ihr einen Wert zuweisen, indem Sie den Zuweisungsoperator = verwenden:
size = 14;
tooMuchCaffeine = true;
In Java gibt es drei Arten von Kommentaren: zwei für reguläre Kommentare im Quellcode und eine für das spezielle Dokumentationssystem javadoc.
Mehrzeilige Kommentare stehen zwischen /* und */, wie in C oder C++. Der gesamte Text zwischen den zwei Begrenzern wird ignoriert:
/* Ich weiß nicht, wie der nächste Teil zustandegekommen ist. Ich habe bis spät in die Nacht gearbeitet und er ergab sich einfach so. Vielleicht haben Elfen das für mich gemacht.
*/
Kommentare können nicht verschachtelt werden. Das heißt, innerhalb eines Kommentars kann kein anderer Kommentar stehen.
Für eine einzelne Kommentarzeile werden doppelte Schrägstriche (//) benutzt. Der gesamte Text bis zum Zeilenende wird dann ignoriert:
int vices = 7; // Sind das wirklich nur sieben?
Die letzte Kommentarart beginnt mit /** und endet mit */. Das sind spezielle Kommentare, die für das javadoc-System benutzt werden. Ansonsten sind sie mit dem ersten Kommentartyp identisch. javadoc dient zum Erzeugen von API-Dokumentation aus dem Code. Sie lernen in diesem Buch nichts über javadoc. Sie finden hierüber Informationen in der Dokumentation zum Sun JDK oder auf der Java-Site von Sun (http://java.sun.com).
Literal ist ein Fachbegriff für Programmiersprachen, der im wesentlichen bedeutet, daß Sie das erhalten, was Sie eingeben. Wenn Sie in einem Java-Programm 4 tippen, erhalten Sie automatisch eine Ganzzahl mit dem Wert 4. Geben Sie 'a' ein, erhalten Sie ein Zeichen mit dem Wert a. Literale dienen zum Bezeichnen einfacher Werte in einem Java-Programm.
Literale sind größtenteils selbsterklärend, jedoch gibt es in Java ein paar Sonderfälle für unterschiedliche Arten von Zahlen, Zeichen, Zeichenketten und boolesche Werte.
In Java gibt es mehrere Ganzzahlenliterale. 4 ist beispielsweise ein dezimales Ganzzahlliteral vom Typ int (obwohl Sie ihm einer Variablen vom Typ byte oder short zuweisen können, weil sie klein ist und damit in solche Typen paßt). Eine dezimale Ganzzahl, das größer ist als int, erhält automatisch den Typ long. Sie können long auch eine kleinere Zahl aufzwingen, indem Sie L oder l an diese Zahl anhängen (4L ist z.B. eine lange Ganzzahl mit dem Wert 4). Negativen Ganzzahlen wird ein Minuszeichen vorangestellt, z.B. -45.
Ganzzahlen können auch oktal oder hexadezimal ausgedrückt werden: Eine führende 0 zeigt an, daß eine Zahl oktal ist, z.B. 0777 oder 0004. Ein führendes 0x (oder 0X) bedeutet, daß die Zahl hexadezimal ist (0xFF, 0XAF45). Hexadezimale Zahlen können normale Ziffern (0-9) und groß oder klein geschriebene Hexzeichen (a-f oder A-F) enthalten.
Gleitpunktliterale bestehen normalerweise aus zwei Teilen: der Ganzzahl und dem Dezimalteil, z.B. 5.77777. Gleitpunktliterale ergeben Gleitpunktzahlen vom Typ double, ungeachtet der Genauigkeit der Zahl. Sie können der Zahl den Typ float aufzwingen, indem Sie den Buchstaben f (oder F) an die Zahl anhängen, z.B. 2.56F.
Mit dem Buchstaben e oder E, gefolgt von dem Exponenten (der eine negative Zahl sein kann), können Sie Exponenten in Gleitpunktliteralen verwenden, z.B. 10e45 oder .36E-2.
Boolesche Literale haben die Schlüsselwörter true und false. Diese Schlüsselwörter können überall dort benutzt werden, wo Sie sie brauchen, um einen Test auszuführen, oder auch als einzig mögliche Werte für boolesche Variablen.
Zeichenliterale werden durch ein einzelnes Zeichen, das zwischen einfachen Anführungszeichen steht, ausgedrückt: 'a', '#', '3' usw. Die Zeichen werden als 16 Bit große Unicode-Zeichen gespeichert. Tabelle 3.2 führt die speziellen Codes auf, die nichtdruckbare Zeichen darstellen, und Zeichen aus dem Unicode-Zeichensatz. Der Buchstabe d in Oktal-, Hex- oder Unicode-Umschaltzeichen stellt eine Zahl oder eine hexadezimale Ziffer dar (a-f oder A-F).
Escapecode |
Bedeutung |
\n |
Neue Zeile |
\t |
Tab |
\b |
Rückschritt |
\r |
Wagenrücklauf (Return) |
\f |
Formularvorschub (Formfeed) |
\\ |
Backslash |
\' |
Einfaches Anführungszeichen |
\" |
Doppeltes Anführungszeichen |
\ddd |
Oktal |
\xdd |
Hexadezimal |
\udddd |
Unicode-Zeichen |
Mehrere Zeichen zusammen bilden eine Zeichenkette (String). In Java sind Zeichenketten Instanzen der Klasse String. Zeichenketten sind keine einfachen Zeichen-Arrays wie in C oder C++, obwohl sie viele arrayähnliche Merkmale aufweisen (z.B. können Sie ihre Länge testen und einzelne Zeichen hinzufügen und löschen). Da String-Objekte in Java echte Objekte sind, umfassen sie Methoden, die es Ihnen ermöglichen, Zeichenketten sehr einfach zu kombinieren, zu testen und zu ändern.
Zeichenkettenliterale bestehen aus mehreren Zeichen zwischen doppelten Anführungszeichen:
"Hallo, ich bin ein Zeichenkettenliteral."
"" // Leere Zeichenkette
Zeichenketten können Konstanten wie neue Zeile, Tab und Unicode-Zeichen enthalten:
"Eine Zeichenkette mit einem Tab \t"
"Verschachtelte Zeichenketten sind \"Zeichenketten in\" anderen Zeichenketten"
"Diese Zeichenkette erhalten Sie mit Java\u2122"
Im letzten Beispiel produziert der Unicode-Code \u2122 ein Warenzeichensymbol ().
Wenn Sie in Ihrem Java-Programm ein Zeichenkettenliteral benutzen, erstellt Java automatisch eine Instanz der Klasse String, für die Sie einen Wert vergeben. Zeichenketten sind in dieser Hinsicht ungewöhnlich. Die anderen Literale verhalten sich nicht so (keiner der primitiven Grundtypen ist ein Objekt). Beim Erstellen eines neuen Objekts ist es normalerweise nötig, explizit eine neue Instanz einer Klasse anzulegen. Sie lernen mehr über Zeichenketten, die String-Klasse und was Sie mit Zeichenketten alles machen können, später in der heutigen Lektion und morgen.
Ausdrücke sind in Java die einfachste Form von Anweisungen, die etwas bewirken. Alle Ausdrücke geben bei der Auswertung einen Wert zurück (was bei anderen Anweisungen nicht unbedingt der Fall ist). Arithmetik und Überprüfungen auf Gleichheit und Größe sind übliche Beispiele von Ausdrücken. Da sie einen Wert zurückgeben, können Sie das Ergebnis einer Variablen zuweisen oder den Wert in anderen Java-Anweisungen testen.
Die meisten Ausdrücke benutzen in Java Operatoren. Operatoren sind spezielle Symbole für Arithmetik, verschiedene Zuweisungsformen, Inkremente, Dekremente und logische Operationen.
Java umfaßt fünf Operatoren für grundlegende Arithmetik (siehe Tabelle 3.3).
Tabelle 3.3: Arithmetische Operatoren
Operator |
Bedeutung |
Beispiel |
+ |
Addition |
3 + 4 |
- |
Subtraktion |
5 7 |
* |
Multiplikation |
5 * 5 |
|
Division |
14 7 |
% |
Modulus |
20 % 7 |
Jeder Operator nimmt zwei Operanden an, je einen auf jeder Seite des Operators. Der Subtraktionsoperator () kann auch zum Verneinen eines einzelnen Operanden benutzt werden.
Die Division einer Ganzzahl ergibt eine Ganzzahl. Da Ganzzahlen keine Dezimalbrüche kennen, wird ein eventueller Rest ignoriert. Der Ausdruck 31 9 ergibt z.B. 3 (9 ist in 31 nur dreimal enthalten).
Der Modulus (%) gibt den Rest aus, nachdem die Operanden ganzzahlig dividiert wurden. 31 9 ergibt z.B. 4, weil 9 in 31 dreimal enthalten ist, so daß 4 übrigbleibt.
Beachten Sie, daß sich aus Ganzzahlen bei den meisten Operationen entweder der Typ int oder long ergibt, ungeachtet des Originaltyps des Operanden (short und byte werden automatisch in int konvertiert). Einer oder beide Operanden vom Typ long ergeben den Typ long. Ist ein Operand eine Ganzzahl (int) und der andere eine Gleitpunktzahl, ergibt sich der Typ float. (Falls Sie an den Einzelheiten interessiert sind, wie Java numerische Typen von einem Typ in einen anderen umwandelt, sehen Sie in der Java Language Specification an der offiziellen Java-Site von Sun unter http://java.sun.com/ nach. Dort steht mehr drin, als ich hier abdecken kann.)
Listing 3.1 ist ein Beispiel einer einfachen Arithmetik in Java.
Listing 3.1: Einfache Arithmetik
1: class ArithmeticTest {
2: public static void main (String args[]) {
3: short x = 6;
4: int y = 4;
5: float a = 12.5f;
6: float b = 7f;
7:
8: System.out.println("x is " + x + ", y is " + y);
9: System.out.println("x + y = " + (x + y));
10: System.out.println("x y = " + (x y));
11: System.out.println("x / y = " + (x / y));
12: System.out.println("x % y = " + (x % y));
13:
14: System.out.println("a is " + a + ", b is " + b);
15: System.out.println("a / b = " + (a / b));
16: }
17: }
Ausgabe:
x is 6, y is 4
x + y = 10
x y = 2
x / y = 1
x % y = 2
a is 12.5, b is 7
a / b = 1.78571
In dieser einfachen Java-Anwendung (beachten Sie die Methode main()) definieren Sie anfänglich vier Variablen in Zeilen 3 bis 6: x und y, die Ganzzahlen (Typ int) sind, sowie a und b, die Gleitpunktzahlen (Typ float) sind. Beachten Sie, daß der Standardtyp für Gleitpunktliterale (z.B. 12.5) double ist. Deshalb müssen Sie ein f nach jeder Zahl (Zeilen 5 und 6) eingeben, damit diese Zahlen den Typ float annehmen.
Der Rest des Programms führt lediglich einige mathematische Aufgaben mit Ganzzahlen und Gleitpunktzahlen aus und gibt die Ergebnisse aus.
Eine Sache ist an diesem Programm noch interessant: die Methode System.-out.println(). Sie sind dieser Methode an den ersten Tagen schon begegnet, haben aber nicht gelernt, was es damit auf sich hat. Die Methode System.out.println() gibt lediglich eine Nachricht an die Standardausgabe Ihres Systems aus auf dem Bildschirm, in einem speziellen Fenster oder in eine Logdatei, je nach System und Entwicklungsumgebung. Die Methode System.out.println() hat ein einzelnes Argument eine Zeichenkette . Sie können aber + benutzen, um mehrere Werte zu verketten, wie Sie später noch lernen.
Die Zuweisung von Variablen ist eine Ausdrucksform. Da ein Zuweisungsausdruck einen Wert ergibt, können wir sie wie folgt verketten:
x = y = z = 0;
In diesem Beispiel haben alle drei Variablen den Wert 0.
Die rechte Seite eines Zuweisungsausdrucks wird immer ausgewertet, bevor die Zuweisung wirksam wird. Das bedeutet, daß Ausdrücke wie x = x + 2 zum richtigen Ergebnis führen. 2 wird zum Wert von x addiert, dann wird dieser neue Wert x erneut zugewiesen. Das ist eine der üblichen Operationen, so daß Java mehrere Operatoren hat, um dafür Kurzformen zu verwenden, die aus C und C++ entlehnt sind. Tabelle 3.4 zeigt diese Kurzformen für Zuweisungsoperatoren.
Tabelle 3.4: Zuweisungsoperatoren
Ausdruck |
Bedeutung |
x += y |
x = x + y |
x -= y |
x + x y |
x *= y |
x = x * y |
x = y |
x = x y |
Wie in C und C++ werden die Operatoren ++ und -- benutzt, um einen Wert um 1 zu erhöhen oder zu verringern. x++ erhöht z.B. den Wert von x um 1 auf die gleiche Weise wie der Ausdruck x = x + 1. x-- senkt den Wert von x um 1. (Im Gegensatz zu C und C++ läßt Java x als Gleitpunktzahl zu.)
Diese Inkrement- und Dekrement-Operatoren können vorangestellt oder hinten angefügt werden. Das bedeutet, daß der Operator ++ oder -- vor oder nach dem zu erhöhenden oder zu senkenden Wert stehen kann. Bei einfachen Inkrement- und Dekrement-Operationen ist das nicht wichtig. In komplexen Zuweisungen, in denen das Ergebnis eines Inkrement- oder Dekrementausdrucks zugewiesen wird, gibt es einen Unterschied.
Betrachten wir beispielsweise folgende zwei Ausdrücke:
y = x++;
y = ++x;
Diese zwei Ausdrücke führen aufgrund der vorangestellten und nachgestellten Operatoren zu unterschiedlichen Ergebnissen. Mit den nachgestellten Operatoren (x++ oder x--) erhält y den Wert von x vor der Erhöhung von x. Mit den vorangestellten Operatoren wird der x-Wert y erst nach der Erhöhung zugewiesen. Wie das alles funktioniert, geht aus dem Beispiel in Listing 3.2 hervor.
Listing 3.2: Vorangestellte und nachgestellte Inkrement-Operatoren testen
1: class PrePostFixTest {
2:
3: public static void main (String args[]) {
4: int x = 0;
5: int y = 0;
6:
7: System.out.println("x and y are " + x + " and " + y );
8: x++;
9: System.out.println("x++ results in " + x);
10: ++x;
11: System.out.println("++x results in " + x);
12: System.out.println("Resetting x back to 0.");
13: x = 0;
14: System.out.println("------------");
15: y = x++;
16: System.out.println("y = x++ (postfix) results in:");
17: System.out.println("x is " + x);
18: System.out.println("y is " + y);
19: System.out.println("------------");
20:
21: y = ++x;
22: System.out.println("y = ++x (prefix) results in:");
23: System.out.println("x is " + x);
24: System.out.println("y is " + y);
25: System.out.println("------------");
26:
27: }
28:}
Ausgabe:
x and y are 0 and 0
x++ results in 1
++x results in 2
Resetting x back to 0.
------------
y = x++ (postfix) results in:
x is 1
y is 0
------------
y = ++x (prefix) results in:
x is 2
y is 2
------------
Im ersten Teil dieses Beispiels haben Sie x sowohl mit prefix als auch mit dem postfix Inkrement-Operatoren inkrementiert. Beide Male wird x jeweils um 1 inkrementiert. In dieser einfachen Form haben beide Operatoren (prefix und postfix) die gleiche Wirkung.
Im zweiten Teil lautet der Ausdruck y = ++x, in dem der postfix-Inkrement-Operator verwendet wird. Bei diesem Ergebnis wird der Wert von x erhöht, nachdem der Wert y zugewiesen wurde. Folglich wird y zuerst dem Originalwert von x (0) zugewiesen, dann wird x um 1 erhöht.
Im dritten Teil wird der Präfixausdruck y = ++x verwendet. Hier verläuft die Prozedur umgekehrt: x wird erhöht, bevor sein Wert y zugewiesen wird. Da x aus dem vorherigen Schritt 1 stammt, wird sein Wert auf 2 erhöht, dann wird dieser Wert y zugewiesen. Sowohl x als auch y ergeben zum Schluß 2.
Java hat mehrere Ausdrücke zum Testen von Gleichheit und Größe. Alle diese Ausdrücke geben einen booleschen Wert (true oder false) zurück. Die Vergleichsoperatoren sind in Tabelle 3.5 aufgeführt.
Tabelle 3.5: Vergleichsoperatoren
Operator |
Bedeutung |
Beispiel |
== |
Gleich |
x == 3 |
!= |
Nicht gleich |
x != 3 |
< |
Kleiner als |
x < 3 |
> |
Größer als |
x > 3 |
<= |
Kleiner als oder gleich |
x <= 3 |
>= |
Größer als oder gleich |
x >= 3 |
Ausdrücke, die boolesche Werte ergeben (wie beispielsweise die Vergleichsoperatoren), können mit logischen Operatoren, die die logischen Verknüpfungen UND, ODER, XOR und das logische NICHT darstellen, kombiniert werden.
Für UND-Kombinationen wird & oder && benutzt. Der Ausdruck ist nur wahr, wenn beide Operanden auf beiden Seiten des Operators wahr sind. Ist ein Ausdruck falsch, ist der gesamte Ausdruck falsch. Der Unterschied zwischen den zwei Operatoren liegt in der Auswertung des Ausdrucks. Mit & werden beide Seiten des Ausdrucks ungeachtet des Ergebnisses ausgewertet. Mit && wird der ganze Ausdruck als falsch angenommen, wenn die linke Seite des Ausdrucks falsch ist (der Wert der rechten Seite spielt keine Rolle). Folglich gibt der Ausdruck false zurück, und die rechte Seite des Ausdrucks wird nicht ausgewertet (auch verkürzter Ausdruck oder verkürzte Ausführung genannt).
Für ODER-Ausdrücke wird oder verwendet. ODER-Ausdrücke ergeben wahr, wenn einer oder beide Operanden wahr sind. Sind beide Operanden falsch, ist der Ausdruck falsch. Wie bei & und && wertet das einzelne beide Seiten des Ausdrucks ungeachtet des Ergebnisses aus. Mit gibt der Ausdruck true zurück, wenn der linke Ausdruck wahr ist, und die rechte Seite wird nicht ausgewertet.
Der XOR-Operator ^ gibt nur wahr aus, wenn seine Operanden unterschiedlich sind (einer ist wahr und der andere falsch), andernfalls ist er falsch (auch wenn beide Operanden wahr sind).
Im allgemeinen werden nur && und häufig als logische Kombinationen benutzt. Die Operatoren &, und ^ werden normalerweise für bitweise logische Operationen verwendet.
Für NICHT wird der Operator ! mit einem einzigen Ausdrucksargument benutzt. Der Wert des NICHT-Ausdrucks ist die Verneinung (Negation) des Ausdrucks. Wenn x wahr ist, ist !x falsch.
Nachfolgend eine kurze Zusammenstellung der bitweisen Operatoren in Java. Sie stammen alle aus C und C++ und werden zur Durchführung von Operationen auf einzelne Bits in Ganzzahlen verwendet. In diesem Buch wird auf bitweise Operationen nicht eingegangen. Das ist ein Thema, das in Büchern über C oder C++ besser abgedeckt ist. Tabelle 3.6 faßt die bitweisen Operatoren zusammen.
Tabelle 3.6: Bitweise Operatoren
Durch die Operatorpräzedenz wird die Reihenfolge vorgegeben, in der Ausdrücke ausgewertet werden. Dadurch kann in manchen Fällen der Gesamtwert eines Ausdrucks ermittelt werden. Betrachten wir als Beispiel folgenden Ausdruck:
y = 6 + 4 2
Je nach dem, ob der Ausdruck 6 + 4 oder 4 2 zuerst ausgewertet wird, kann y einen Wert von 5 oder 8 ergeben. Die Operatorpräzedenz gibt die Reihenfolge vor, in der Ausdrücke ausgewertet werden, so daß das Ergebnis eines Ausdrucks vorhergesagt werden kann. Im allgemeinen werden Inkremente und Dekremente vor arithmetischen Ausdrücken, arithmetische Ausdrücke vor Vergleichen und Vergleiche vor logischen Ausdrücken ausgewertet. Zuweisungsausdrücke werden zuletzt ausgewertet.
Tabelle 3.7 zeigt die spezifische Präzedenz der verschiedenen Operatoren in Java. Die Operatoren oben in der Tabelle werden zuerst ausgewertet. Operatoren in der gleichen Zeile haben die gleiche Rangfolge und werden von links nach rechts ausgewertet, je nach dem, wie sie im Ausdruck erscheinen. Beim Ausdruck y = 6 + 4 2 wissen Sie jetzt anhand der Tabelle, daß die Division vor der Addition ausgewertet wird, deshalb ergibt sich für y ein Wert von 8.
Tabelle 3.7: Operatorpräzedenz
Sie können die Reihenfolge, in der Ausdrücke ausgewertet werden, jederzeit ändern, indem Sie die zuerst auszuwertenden Ausdrücke zwischen Klammern setzen. Sie können Klammern verschachteln, um sicherzustellen, daß Ausdrücke in der gewünschten Reihenfolge ausgewertet werden (der innerste in Klammern stehende Ausdruck wird zuerst ausgewertet). Der folgende Ausdruck ergibt einen Wert von 5, weil der Ausdruck 6 + 4 zuerst ausgewertet wird, dann wird das Ergebnis dieses Ausdrucks (10) durch 2 geteilt:
y = (6 + 4) 2
Klammern sind auch in Fällen nützlich, in denen die Reihenfolge eines Ausdrucks nicht ganz klar ist, d.h. sie machen den Code übersichtlicher. Das Einfügen von Klammern kann nicht schaden, deshalb können Sie reichlich davon Gebrauch machen, um die Auswertung von Ausdrücken übersichtlicher zu gestalten.
Ein besonderer Ausdruck in Java ist die Verwendung des Additionsoperators (+) zum Erstellen und Verketten von Zeichenketten (Strings). In den meisten bisherigen Beispielen sind zahlreiche Zeilen vorgekommen, die in etwa so aussehen:
System.out.println(name + " is a " + color + " beetle");
Die Ausgabe dieser Zeile (auf dem Standardausgabegerät) ist eine einzelne Zeichenkette. Die Werte der Variablen (hier name und color) stehen innerhalb der Zeichenkette an den richtigen Stellen. Was also passiert hier?
In Zeichenketten und anderen Objekten erstellt der Operator + eine einzelne Zeichenkette, die die Verkettung aller Operanden beinhaltet. Ist einer der Operanden in der Zeichenverkettung keine Zeichenkette, wird er automatisch in eine Zeichenkette konvertiert, so daß es einfach ist, diese Arten von Ausgabezeilen zu erstellen.
Die Zeichenverkettung vereinfacht den Aufbau von Zeilen wie im vorherigen Beispiel. Um eine Zeichenkette zu erstellen, fügen Sie einfach alle Teile, d.h. die Beschreibungen und die Variablen, zusammen und geben sie auf der Standardausgabe, z.B. am Bildschirm oder in einem Applet oder sonstwo, aus.
Der Operator +=, den Sie schon gelernt haben, funktioniert ebenfalls bei Zeichenketten. Betrachten wir folgenden Ausdruck:
myName += " Jr.";
Dieser Ausdruck entspricht:
myName = myName + " Jr.";
genauso wie bei Zahlen. In diesem Fall wird der Wert von myName (der John Smith oder sonst etwas mit Jr. am Ende (John Smith Jr.) sein kann) geändert.
Wie Sie in den ersten zwei Lektionen gelernt haben, besteht ein Java-Programm vorwiegend aus Klassen und Objekten. Klassen und Objekte bestehen ihrerseits aus Methoden und Variablen, während Methoden aus Anweisungen und Ausdrükken bestehen. Anweisungen und Ausdrücke haben Sie in der heutigen Lektion gelernt. Das sind die grundlegenden Bausteine, die es Ihnen ermöglichen, Klassen und Methoden zu erstellen und zu einem ausgewachsenen Java-Programm zusammenzusetzen.
Heute haben Sie auch Variablen gelernt, wie sie deklariert und wie ihnen Werte zugewiesen werden. Sie haben Literale zum einfachen Erstellen von Zahlen, Zeichen und Zeichenketten, Operatoren für arithmetische Operationen, Tests und andere einfache Operationen kennengelernt. Mit dieser Basissyntax lernen Sie morgen, wie man mit Objekten arbeitet und einfache nützliche Java-Programme schreibt.
Am Ende dieser Zusammenfassung finden Sie in Tabelle 3.8 eine Zusammenstellung aller Operatoren, die Sie heute gelernt haben, damit Sie sie jederzeit übersichtlich nachschlagen können.
+
Tabelle 3.8: Zusammenstellung aller Operatoren
F Ich habe hier nichts darüber gelesen, wie man Konstanten definiert.
A Sie können in Java keine lokalen Konstanten, sondern nur Konstanteninstanzen und Klassenvariablen erstellen. Das alles lernen Sie in der morgigen Lektion.
F Was passiert, wenn man eine Variable als Ganzzahltyp deklariert und ihr dann eine Zahl zuweist, die über den Wertbereich der Variablen hinausgeht?
A Vom logischen Gesichtspunkt müßte man annehmen, daß die Variable einfach in den nächstgrößeren Typ konvertiert wird, das ist aber nicht der Fall. Was wirklich passiert, nennt man Overflow (Überlauf). Das bedeutet, daß Zahlen, die über den Bereich der Variablen hinausgehen, auf die kleinstmögliche negative Zahl des jeweiligen Typs gekürzt werden, dann beginnt die Zählung wieder rückwärts hin zu Null.
Da dies zu verwirrenden (und falschen) Ergebnissen führen kann, muß man sicherstellen, daß für alle Zahlen der richtige Ganzzahltyp deklariert wird. Besteht auch nur der geringste Verdacht, daß sich durch eine Zahl mit dem jeweiligen Typ ein Überlauf ergibt, verwendet man sicherheitshalber den nächstgrößeren Typ.
F Wie kann man den richtigen Typ für eine bestimmte Variable ermitteln?
A Wenn Sie die Grundtypen (int, float, boolean usw.) verwenden, besteht keine Möglichkeit. Sie können aber den Wert durch Casting (das lernen Sie morgen) in einen anderen Typ konvertieren.
Falls Sie mit Klassentypen arbeiten, können Sie den Operator instanceof verwenden. Auch hierüber lernen Sie morgen mehr.
F Warum werden in Java so viele Kurzformen für arithmetische und Zuweisungsoperatoren verwendet? Der Code wird dadurch doch unübersichtlich.
A Die Java-Syntax basiert auf C++ und damit auf C. Eines der impliziten Ziele von C ist die Fähigkeit, mit minimalem Tippaufwand leistungsstarke Ergebnisse zu erzielen. Deshalb sind Kurzformen für Operatoren üblich.
Es gibt keine Regel, die besagt, daß Sie diese Kurzformen für Operatoren in Ihren eigenen Programmen verwenden müssen. Wenn Sie finden, daß ausgeschriebener Code übersichtlicher ist, brauchen Sie die Kurzformen nicht zu verwenden.
F Sie haben in diesem Kapitel einfache mathematische Operationen über die Verwendung von Operatoren behandelt. Bietet Java keine Möglichkeit, komplexere mathematische Operationen durchzuführen?
A Selbstverständlich. Eine spezielle Klasse im Paket java.lang namens java.-lang.Math umfaßt eine Reihe von Methoden für exponentielle, trigonometrische und andere mathematische Operationen. Da diese Methoden über die Verwendung der Klasse Math aufgerufen werden, sind das sogar ausgezeichnete Beispiele von Klassenmethoden. Sie lernen morgen mehr zu diesem Thema.
(c) 1997 SAMS