Konventionen, Darstellungsweisen, Operatoren |
|
meinpaket, MeineKlasse, meineMethode, meineVariable, MEINE_KONSTANTE | Übliche Schreibweise: Packages klein, Klassen groß, Methoden und Variablen klein und Konstanten komplett groß. |
012, 0x3F, 12, -5, 3L, 3.7, 1.2e+2 | Zahlendarstellung im Source-Code: 0... = Oktalzahl, 0x... Hexadezimalzahl, normale Ganzzahl positiv, negativ, als long-Wert, Fließkommazahl, Exponentialdarstellung. |
\b, \f, \n, \r, \t, \", \', \\, \0???, \u0x???? | Sonderzeichen: Backspace, Formfeed, Newline, Carriage Return, Tabulator, ", ', \, Oktalzeichen (0000 <= 0??? <= 0377), Unicode-Zeichen (u0x0000 <= u0x???? <= u0xFFFF). |
\r, \n, \r\n, CRLF | Statt "\r" (Mac), "\n" (Unix), "\r\n" bzw. CRLF (Windows) sollte das plattformunabhängige System.getProperty("line.separator") bevorzugt werden. |
++ -- +/- * / % + - | Arithmetische Operatoren. |
~ << >> >>> & | ^ | Bitarithmetische Operatoren (>>> bedeutet Shift nach rechts, aber mit Auffüllen von links mit Nullen). |
! & ^ | && || | Logische Operatoren: ! = Negation, & ^ | = boolesches AND / XOR / OR (Ausdrücke werden komplett ausgewertet), && || = bedingtes AND / OR (Berechnung der Ausdrücke bricht ab, wenn logisches Ergebnis klar). |
< > <= >= == != | Vergleichsoperatoren. |
= += -= *= /= %= &= |= ^= <<= >>= >>>= | Zuweisungsoperatoren. |
( ) ? : ; | Bedingungsoperator. |
instanceof | Instanz von Klasse. |
// ... /* ... */ /** ... */ |
Kommentare: // bis Zeilenende, /* */ auch über mehrere Zeilen, /** */ Doku für JavaDoc. |
Programmflusssteuerung, Anweisungen |
|
if( ... ) { ...; } else { ...; } switch( ... ) { case ...: ...; break; default: ...; } while( ... ) { ...; } do { ...; } while( ... ); for( ...; ...; ... ) { ...; } continue, break, break meinLabel |
if, switch, while, do-while, for, ... |
Fehlerbehandlung |
|
try { ...; } catch( Exception1 ex ) { ....; } catch( Exception2 ex ) { ....; } finally { ...; } |
try-catch-finally. |
throw new Exception( "Fehler ..." ); | throw: Auslösen einer Exception. |
// Methode kann IOException auslösen: public int meineMethode() throws IOException { ... } // Aufruf der Methode erfordert try-catch: try { int i = meineMethode(); } catch( IOException ex ) { System.out.println( ex.getMessage() ); } |
throws: Fehlerbehandlung erzwingen. |
Einfache Datentypen |
|
boolean, char, byte, short, int, long, float, double |
Primitive Datentypen (char = 16-Bit-Unicode-Zeichen, byte/short/int/long = 8/16/32/64 Bit). |
Integer.MIN_VALUE, Integer.MAX_VALUE | Minimaler (negativer) und maximaler (positiver) Integer-Wert. |
Double.MIN_VALUE, Double.MAX_VALUE | Kleinster und größter double-Wert. Achtung: Beide Werte sind positiv ! |
boolean b = true; int i, j; double d = 3.14; |
Bei primitiven Datentypen reicht Deklaration zur Erzeugung. Objekte dagegen müssen mit Hilfe des new-Operators erzeugt werden. Nur String- und array-Objekte können außer per new auch durch Zuweisung von Literalen erzeugt werden. |
String s1 = "Hallo"; String s2 = new String( "Hallo" ); StringBuffer strBuf = new StringBuffer(); strBuf.setCharAt(3,'x'); strBuf.insert(4,"Hi"); strBuf.append("End"); |
String ist eine unveränderbare Zeichenkette, StringBuffer eine veränderbare. Werden viele Strings zu einem langen String kopiert, ist StringBuffer.append() wesentlich schneller als String s = s1 + s2 + ... Anders als in C/C++ sind Zeichenketten nicht Null-terminiert. |
String s = "" + myDouble; String s = String.valueOf( myDouble ); String s = Double.toString( myDouble ); |
Wandelt Zahl zu String (erste Version ist übersichtlicher, die beiden anderen Versionen können schneller sein). |
int i = Integer.parseInt( s ); double d = Double.valueOf( s ).doubleValue(); |
Wandelt String zu Zahl. |
int meinArray[]; // Deklaration (wie C/C++) int[] meinArray; // üblichere Deklaration int[] meinArray = { 3, 5, 9 }; // Array anlegen meinArray = new double[12000]; // Array anlegen int[] meinArray = new int[20]; // Array anlegen int[][] arr2D = new int[9][8]; // zweidimensional int arrLaengeY = arr2D.length; // Zeilenzahl int arrLaengeX = arr2D[0].length; // Spaltenzahl String[] arr = { "ab", "mn", "xy" }; String[] arr = new String[] { "abc", "xyz" }; myMethodeNeedsArr( new String[] {"abc","xyz"} ); MyClass[] myArr = new MyClass[22]; myArr[i] = new MyClass(); // 2 x 'new' |
Arrays (Felder). Mit new reservierter Speicher braucht nicht nach Gebrauch freigegeben zu werden (Freigabe kann aber durch Zuweisung von null beschleunigt werden). Der Ausdruck "new String[] { "abc", "xyz" }" kann einer Variablen (hier arr) zugewiesen werden. Er kann aber auch als anonymes Array (Array ohne Namen) z.B. als String-Array-Parameter einer Methode (hier myMethodeNeedsArr()) übergeben werden. |
arr2 = arr1.clone(); System.arraycopy( arr1, 0, arr2, 0, arr2.length ); |
clone() kopiert Arrays komplett, arraycopy() kann auch teilweise kopieren. Beide kopieren Arrays von Objekten (insbesondere bei geschachtelten Arrays) nur flach, also nur die Objektreferenzen. Tiefes Kopieren kann mit Serialisierung erreicht werden. |
Vector v = new Vector(); v.addElement( new MeineKlasse( "xy " ) ); Object obj = v.elementAt( 0 ); if( obj instanceof MeineKlasse ) ((MeineKlasse)obj).meineMethode(); Enumeration en = v.elements(); while( en.hasMoreElements() ) { Object obj = en.nextElement(); ...; } String[][] ssArr = (String[][])(v.toArray( new String[v.size()][2] )); |
Während Arrays eine feste Länge besitzen, sind Vektoren variabel. Außerdem können in einem Vector Instanzen verschiedener Klassen gespeichert werden. |
LinkedList, ArrayList, HashSet, TreeSet, HashMap, TreeMap, Vector, Stack, Dictionary, Hashtable, Properties, BitSet |
Collections siehe java-collections.htm. |
Klassen, Interfaces, Adapter |
|
class MeineKlasse { ... } // definieren MeineKlasse meinObjekt; // deklarieren meinObjekt = new MeineKlasse(); // instanziieren MeineKlasse meinObjekt = new MeineKlasse(); //dekl.+inst. |
Klasse definieren, deklarieren und instanziieren. |
public class MeineKlasse { int i = 0; String str = "Hallo"; public double meineMethode() { return 3.14; } } |
Klassendefinition (mit Variablen und Methoden) (Variablen werden auch Attribute genannt). |
MeineKlasse meinObjekt = new MeineKlasse(); int i = meinObjekt.i; double f = meinObjekt.meineMethode(); System.out.println( meinObjekt.str ); |
Objekt (Instanz der Klasse) benutzen. |
class MeineKlasse { public MeineKlasse( int i ) { ...; } public MeineKlasse( double f ) { ...; } protected void finalize() { ...; } } |
Klassen können einen oder mehrere (überladene) Konstruktoren und einen Finalizer haben. Beachten: Es kann passieren, dass finalize() nicht aufgerufen wird (z.B. Programmende vor GC). Destruktoren wie in C++ gibt es nicht (wegen automatischer Garbage Collection). |
class MeineKlasse { int x; public MeineKlasse( int x ) { this.x = x } } |
Zugriff auf verdeckte Variable mit this. this ist eine Referenz auf die zugehörige Instanz. |
class MeineKlasse { public MeineKlasse( int a, int b ) { ...; } public MeineKlasse() { this( 0, 0 ); } } |
Überladene Konstruktoren. Ein Konstruktor kann einen anderen mit this() aufrufen. Nur Konstruktoren können this() aufrufen. |
class Koordinate { int x, y; public maximum( Koordinate k ) { if( laenge() > k.lange() ) return this; else return k; } } |
Returniere eigenes Objekt mit this. |
class MeineKlasse extends AndereKlasse { ... } | Neue Klasse von bestehender ableiten (Vererbung). |
class Rechteck extends Figur { ... } class Kreis extends Figur { ... } Figur f = new Kreis( .... ); if( f instanceof Kreis ) ((Kreis)f).getRadius(); |
Variablen vom Typ der Superklasse können vererbte Klassen zugewiesen werden. Mit instanceof kann die Klasse überprüft werden. |
public void ausgeben() { System.out.print( "Radius=" + radius + ", " ); super.ausgeben(); } |
super: Referenz auf Vorfahrenklasse. |
Kreis( int x, int y, int rad ) { super( x, y ); radius = rad; } |
super() führt den Konstruktor der Vorfahrenklasse aus, darf nur in Konstruktoren aufgerufen werden und muss dort die erste Anweisung sein. |
interface MeineInterfaceKlasse { public static final double PI = 3.1416; public int meineMethode( int x, y ); } |
Ein Interface ist eine spezielle Klassendeklaration (ähnlich abstrakten Klassen, s.u.) und kann nur Methoden ohne Implementierung (abstract) sowie Konstanten (static final) beinhalten. In Java gibt es (anders als in C++) keine Mehrfachvererbung und keine Funktionszeiger. Beide Funktionalitäten werden per Interface erreicht. |
interface MeineZweiteInterfaceKlasse extends MeineErsteInterfaceKlasse {... } |
Interface-Klassen können von anderen Interface-Klassen abgeleitet sein. |
class MeineKlasse extends AndereKlasse implements Interface1, Interface2 { ... } |
Eine Klasse kann mehrere Interfaces implementieren und zusätzlich von einer anderen Klasse abgeleitet sein. |
...addActionListener( new ActionListener() { public void actionPerformed( ActionEvent ev ) { meineMethode(); } } ); |
Listener reagieren auf Ereignisse (z.B. das Betätigen von GUI-Kontrollelementen). |
addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent ev ) { ...; } } ); |
Adapter sind vordefinierte Klassen, die alle Methoden eines Interface implementieren, damit nur noch relevante überschrieben werden müssen. |
Modifizierer |
|
public abstract class Figur { public abstract double getFlaeche(); } |
abstract-Methoden enthalten keinen Body und müssen in der abgeleiteten Klasse überschrieben werden. Alle abgeleiteten Klassen beinhalten diese Methode. Eine Klasse mit abstrakten Methoden heißt abstrakte Klasse und kann nicht instanziiert werden, sondern nur als Vorlage zur Ableitung dienen. Wird eine Methode in zwei von der gleichen Vorfahrenklasse abgeleiteten Klassen unterschiedlich implementiert und auf diese Methoden über eine Variable vom Typ der Vorfahrenklasse zugegriffen, nennt man das Polymorphie. |
final |
Eine final-Variable ist eine nicht änderbare Konstante. Eine final-Methode kann nicht überschrieben werden. Von final-Klasse kann keine weitere Klasse abgeleitet werden. |
static |
static-Variable (Klassenattribut) existiert nur einmal für alle Instanzen einer Klasse. static-Methode (Klassenmethode) kann ohne Instanziierung aufgerufen werden (kann aber nicht this verwenden). Zugriff auf beide über Klassenname und nicht Instanzname. |
private, protected, public |
Sichtbarkeits- und Zugriffsmodifizierer. Der Aufruf von Methoden ist am schnellsten, wenn sie als private static final und nicht als synchronized gekennzeichnet sind. |
synchronized | Mit synchronized gekennzeichnete Objekte, Code-Abschnitte oder Methoden werden nicht gleichzeitig von mehreren Threads verändert bzw. durchlaufen. |
volatile | Mit volatile müssen Variablen gekennzeichnet werden, die möglicherweise durch äußere Einflüsse (z.B. Hardware-Interupts oder DMA) ihren Speicherinhalt ändern und deshalb nicht vom Compiler-Optimierer z.B. als Register-Variable angelegt werden dürfen. |
transient | Mit transient gekennzeichnete Variablen werden bei Serialisierungen zur persistenten Abspeicherung eines Objekts nicht mit gespeichert. |
native | Methoden mit Einbindung von nativem Code (z.B. Windows-Funktionen). |
Packages |
|
package meinpaket; | package-Anweisung zu Beginn von Java-Source-Dateien organisiert diese Klassendateien zu einem Package (Paket). |
meinpaket.MeineKlasse.meineMethode(); | Wird keine import-Deklaration verwendet, muss zur Verwendung einer Klasse aus einem Package der Package-Name mit angegeben werden. |
import meinpaket.*; MeineKlasse.meineMethode(); |
Importierung eines Packages und Benutzung einer Package-Klasse ohne Angabe des Package-Namens. |
java.lang, java.util, java.io, java.net, java.awt, java.applet |
Einige der im Java SE enthaltenen Standard-Packages: Basisklassen, Utilities, Ein-/Ausgabe, Netzwerk, grafische Ausgabe, Applet. |
Formatierung, Rundung |
|
Anders als in C/C++ gibt es in Java keine (fehlerträchtige) printf- oder sprintf-Funktion. Einige Ausgabeformatierungen können mit DecimalFormat, NumberFormat und MessageFormat erreicht werden. Kann auf sprintf() nicht verzichtet werden, gibt es Java-Nachbildungen unter http://developer.java.sun.com/developer/technicalArticles/Programming/sprintf und http://www.gkrueger.com/java/printf.html. Eine häufige Aufgabe ist das Runden auf zwei Nachkommastellen. Bei Rundungen muss beachtet werden, dass "i = (int)(d + 0.5)" bei negativen Zahlen falsch rundet, deshalb muss mit Math.round() gerundet werden. |
|
// java.lang.Math: myDouble = Math.round( myDouble * 100. ) / 100.; |
Double-Wert runden auf häufig zwei Nachkommastellen: - Falls zweite Nachkommastelle 0 ist: Nur eine Nachkommastelle. - In seltenen Fällen hat das Ergebnis wegen Rundungsfehlern viele Nachkommastellen (z.B. 1.9000000000000001 oder 4.8999999999999995). |
import java.text.DecimalFormat; DecimalFormat df = new DecimalFormat( "0.00" ); String s = df.format( myDouble ); |
Double-Wert zu String mit genau zwei Nachkommastellen und aktuellem landesspezifischen Dezimaltrennzeichen. |
import java.util.*; DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(Locale.GERMAN); df.applyPattern( "#,###,##0.00" ); String s = df.format( myDouble ); |
Double-Wert zu String mit genau zwei Nachkommastellen, dem deutschen Dezimaltrennzeichen ',' (Komma) und dem deutschen Tausender-Trennzeichen '.' (Punkt). |
import java.math.BigDecimal; BigDecimal myDec = new BigDecimal( myDouble ); myDec = myDec.setScale( 2, BigDecimal.ROUND_HALF_UP ); |
Double-Wert runden auf genau zwei Nachkommastellen (nicht verwechseln: java.math und java.lang.Math). |
Eine andere häufige Aufgabe ist das Verlängern eines Strings auf eine feste Länge: | |
final String sFillStrWithWantLen = " "; int len = str.length(); if( len < sFillStrWithWantLen.length() ) str = (sFillStrWithWantLen + str).substring(len); |
Zu str werden links soviele Leerzeichzeichen hinzugefügt, dass der resultierende String die Länge von sFillStrWithWantLen bekommt (rechtsbündige Ausrichtung). |