Lexikalische Elemente
Kommentare
Bezeichner
reservierte Bezeichner und Zeichen
Variablen
Elementare Datentypen
Operatoren
Anweisungen
Kontrollstrukturen
Felder, Arrays
Die elementaren Bestandteile von Java Programmen sind:
White-Space: Leerraum, Tabs, Zeilenumbruch
Kommentare
Bezeichner
Schlüsselwörter
Literale
Interpunktionszeichen
Operatoren
Es gibt drei Arten von Kommentaren in Java:
/* Kommentar */
Für längere Kommentare über mehrere Zeilen,
praktisch auch zum vorübergehenden Herauskommentieren
von Programmteilen
// Kommentar
Ab // werden die Zeichen bis zur nächsten Zeile
ignoriert, gebräuchlich für Kommentare innerhalb
der Programmzeilen selbst
/** Kommentar */
Kommentar zur Programmdokumentation mit javadoc.
Über bestimmte Tags, z.B.
@author text
@version text
@param name Erläuterung
@return Erläuterung
lässt sich die Dokumenation sehr übersichtlich gestalten.
Namen von Variablen und Methoden etc.
beginnen mit Buchstaben, dürfen "_" und "$" enthalten.
Schlüsselwörter (key words)
Eigene Objekte und Variablen kann man beliebig nennen, bis auf folgende, von Java reservierten Worte:
abstract double int strictfp ** assert ** boolean else interface super break extends long switch byte final native synchronized case finally new this catch float package throw char for private throws class goto * protected transient const * if public try continue implements return void default import short volatile do instanceof static while null true false
* z.Zt unbenutzt, ** neu in Java 2
( ) { } [ ] ; , . = - + * / % < > ! ? & | ~
Daneben gibt es eine Reihe von Methodennamen mit speziellen
Bedeutungen (z.B. main()
oder run()
).
Sie werden in der Regel durch Interfaces vorgeschrieben.
Eine Ausnahme ist die Methode main()
.
In Java sind die primitiven Datentypen architektur-unabhängig definiert. Eine Zusammenstellung befindet sich in Abbildung 1.3.
Datentyp | Inhalt | Größe |
---|---|---|
boolean | true oder false | 1 bit |
char | Unicode Zeichen | 16 bits |
byte | signed integer | 8 bits |
short | signed integer | 16 bits |
int | signed integer | 32 bits |
long | signed integer | 64 bits |
float | IEEE754 float | 32 bits |
double | IEEE754 double | 64 bits |
String | Zeichenkette | beliebig |
Objekt-Referenz | Zeiger, Pointer | null oder Referenz |
Typ | Art (Bereich) |
---|---|
ganze Zahlen, Zweierkomplement-Darstellung | |
byte | 8-bit Integer mit Vorzeichen (-128 bis 127) |
short | 16-bit Integer mit Vorzeichen (-32.768 bis 32.767) |
int | 32-bit Integer mit Vorzeichen (-2.147.483.648 bis 2.147.483.647) |
long | 64-bit Integer mit Vorzeichen (-9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807) |
reele Zahlen | |
float | 32-bit IEEE 754 Fliesskomma (-3.40282347e+38 bis 3.40282347e+38), 1 Bit Vorzeichen, 8 Bit Exponent, 23 Bit Mantisse |
double | 64-bit IEEE 754 Fliesskomma (-1.7976931348623157e+308 bis 1.7976931348623157e+308) 1 Bit Vorzeichen, 11 Bit Exponent, 52 Bit Mantisse |
andere Typen | |
char | 16-bit Unicode character (65536 Zeichen). |
boolean | Boolscher Wert (wahr oder falsch) |
Die Größe der Datentypen ist unabhängig vom Rechnersystem und der Java-Implementierung!
Zu allen elementaren Datentypen existieren sogenannte Hüllklassen
Byte
, Short
, Integer
,
Long
, Float
, Double
,
Character
und Boolean
.
Beispiel:
public class PrimitivTypen { // lexikalische Typen sind int und double // andere direkte Wertzuweisungen müssen // "gecastet" werden z.B.: byte b = (byte)37; short s = (short)37; int i = 37; // dezimal int j = 012; // oktal -> 10 dez int k = 0x14; // hexadezimal -> 20 dez long l = 37L; float f = 0.37F; double d = 0.37; double e = 0.37e+10; char c = 'K'; char u = (char)90; // 'Z' int m = u; boolean w = true; }
Abstraktion für Werte, Speicherstelle, Schublade
Name: ein Bezeichner
Typ: ein elementarer Typ oder Klassen-/Objekt-Typ
Wert: Bitmuster im Speicher
Semantik: Bedeutung des Bitmusters entsprechend dem Typ
Definition durch
typ name;
bzw.
typ name = anfangswert;
Ändern des Wertes durch Zuweisung name = neuerwert
Definition von Konstanten durch
final typ NAME = wert;
Es gibt unter anderem folgende drei Arten von Variablen:
lokale Variablen:
werden lokal innerhalb eines {...}-Blocks (z.B. Methode)
definiert und sind nur dort verfügbar.
Objekt-Variablen:
werden in Klassen definiert und gehören zum
erzeugten Objekt
Klassen-Variablen:
werden in Klassen definiert und sind ohne erzeugtes Objekt
verwendbar
Beispiel:
public class Variablen { // Variablen haben // einen Namen, einen Wert und einen Typ int eineVariableVomTypint; // = 0 int i = 3; // bitmuster: 0...011 long index = 0; Integer x; // = null Integer y = new Integer( -3 ); Integer z = 5; // auto boxing ab JDK 1.5 int j = y; // auto unboxing ab JDK 1.5 //int k = x; // Fehler, da x == null String s = "Eine Zeichenkette"; String w$2 = s + " mit Erweiterung"; java.util.Date d_1 = new java.util.Date(); }
Zur Verknüpfung von elementaren Datentypen:
postfix operators [] . (params) expr++ expr-- unary operators ++expr --expr +expr -expr ~ ! creation or cast new (type)expr multiplicative * / % additive + - shift << >> >>> relational < > <= >= instanceof equality == != bitwise AND & bitwise exclusive OR ^ bitwise inclusive OR | bitwise NOT ~ logical AND && logical OR || logical NOT ! conditional ? : assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=
Beispiel:
public class Operatoren { public void numericalops() { int n = 43; n += 7; // ist eine Abkuerzung von n = n + 7; // dies funktioniert auch mit -, /, >>, etc. n = n * 2; // verdoppelt n n = n / 2; // teilt n ganzzahlig durch 2 n = n % 2; // Rest der ganzzahligen Division } strictfp public void floatingpointops() { double d = 2.71; float one = 1.0f; float f = 1.0f / (float)2; // liefert das float- // Divisionsergebnis double zero = 0.0; // 0.0 zero = 1/2; // 0.0 double p = d / zero; // Double.POSITIVE_INFINITY double n = -d / zero; // Double.NEGATIVE_INFINITY double z = zero / zero; // NaN = not a number z = d * zero + p; } public void logicalops() { boolean bool = true && false; // bool ist false bool = true || false; // bool ist true bool = true == false; // bool ist false bool = false != true; // bool ist true bool = !bool; // ! nimmt eine logische Negierung vor // bool ist jetzt gleich false bool = 4 >= 3; // bool ist true bool = 4 != 4; // bool ist false } public void difficultops() { int var = 0; if (var++ < 0); // ist gleichbedeutend mit if (var < 0); var = var + 1; if (--var == 2); // ist gleichbedeutend mit var = var - 1; if ( var == 2 ); int a = 1; int conditional = ( a == 4 ? 3 : -2 ); // conditional ist jetzt -2 } public void bitwiseops() { int i = 3; i = i << 1; // i ist jetzt 6 i = i & 7; // i ist jetzt 6 i = i | 3; // i ist jetzt 7 } }
Zuweisung, Zusammenfassung von mehreren Anweisungen in Blöcken. Lebensdauer und Sichtbarkeit von Variablen in Blöcken.
Anweisung: Zuweisung, Methodenaufruf, bestimmte Ausdrücke
Zusammenfassung mehrerer Anweisungen in einem Block: { ... }
Variablen, die in einem Block definiert werden, sind nach seinem Verlassen nicht mehr sichtbar
in einem Block dürfen keine Variablen deklariert werden, die in einem umgebenden Block schon deklariert sind
statement; name = wert; name.methode(); name++; { statement1, ..., statementn; }
Beispiel:
public class Sichtbarkeit { void anweisung() { int x; x = 3; System.out.println("x = " + x); x++; } void blocks() { int x = 1; int y; { int x = 2; // fehler x wird verdeckt y = x; } y = x; } void leben() { int x = 1; { int y = 2; } x = y; // fehler y existiert nicht mehr } }
Kontrollstrukturen dienen dem Ausführen von Programmteilen in Abhängigkeit von sich ändernden Bedingungen.
Statement Keyword decision making if-else, switch-case loop for, while, do-while miscellaneous break, continue, label:, return
Java hat die üblichen auch von C und C++ bekannten while-, do- und for-Schleifen-Konstrukte.
if ( condition ) { statements } else { statements } for ( initial; condition; increment ) { statements } for ( Type var : collection ) { statements } while ( condition ) { statements } do { statements } while ( condition ); switch ( intVar ) { case a: statements; break; case b: statements; break; ... default: statements; }
break und continue können analog zu C/C++ in einer Schleife benutzt werden, um die gesamte Schleife zu verlassen, bzw. um die aktuelle Schleife zu beenden.
Beispiel:
public class Kontrollstrukturen { public void decision() { int variable; variable = 2; if (variable > 1 && variable == 2) { variable = variable - 1; } else { variable = variable + 1; } switch (variable) { case 0: case 1: // variable ist 0 oder 1 break; case 2: variable = variable * 2; break; default: // variable ist nicht 0, 1 oder 2 } } public void loop() { // dreimal dieselbe Schleife for (int index = 0; index < 4; index = index + 1) { // tue irgendwas 4 mal } int index = 0; while (index < 4) { index = index + 1; } index = 0; do { index = index + 1; } while (index < 4); } public void miscellaneous() { int i = 0; while (1 > 0) { i = i + 2; if (i > 5) break; // verlaesst die while-Schleife continue; // faengt sofort wieder am // Schleifen-Kopf an } return; // beendet die Methode sofort } }
weitere Beispiele zu Schleifen:
for (int i = 0; i < args.length-1; i++ ) { for (int j = i+1; j < args.length; j++) { if ( args[i].equals( args[j] ) ) { ... } } } for ( Iterator it = verschiedeneArgs.keySet().iterator(); it.hasNext(); /* fehlt */ ) { Object arg = it.next(); ... } Iterator it = verschiedeneArgs.keySet().iterator(); while ( it.hasNext() ) { Object arg = it.next(); ... } // JDK 1.5 for for ( Object arg : verschiedeneArgs.keySet() ) { ... }
Java Syntax aus der Sprachdefinition.
Ein Array, d.h. einen Vektor oder eine Matrix, kann man ebenfalls durch new erzeugen.
byte[] buffer = new byte[4096]; byte[] data = new byte[4096]; int[][] plot = new int[64][64]; ... Date[] ds = new Date[16];
Auf die Elemente eines Arrays kann über ihren Index zugegriffen werden.
for (int i=0; i < buffer.length; i++) { buffer[i] = data[i]; } for (int i=0; i < ds.length; i++) { ds[i] = new Date(); }
In der length Variablen eines Array Objekts steht die Information über die Länge bereit.
Bemerkung:
Java erlaubt (aus Gründen der Kompatibilität zu C/C++) auch die
Notation byte buffer[] = new byte[4096]
.
Wir werden davon aber keinen Gebrauch machen.
Beispiel:
import java.util.Date; public class Reihungen { byte[] buffer = new byte[4096]; byte[] data = new byte[4096]; int[][] plot = new int[64][64]; float[] stat = { 1.0f, 2.0f, 3.14f, 2.71f, 1.99f }; Date[] ds = new Date[16]; public void initialisieren() { for (int i=0; i < buffer.length; i++) buffer[i] = (byte)i; for (int i=0; i < ds.length; i++) { ds[i] = new Date(); } } public void kopieren() { for (int i=0; i < buffer.length; i++) data[i] = buffer[i]; } public int summieren() { int sum = 0; for (int i=0; i < buffer.length; i++) { sum += buffer[i]; } return sum; } }
© Universität Mannheim, Rechenzentrum, 2000-2008.
Heinz KredelLast modified: Sun Oct 5 15:19:27 CEST 2008