Java-Grundlagen

+ andere TechDocs
+ andere Java-Docs
+ Java-Installation
+ Java-Beispiele
+ JSP, SQL
+ Webanwendungen
+




Inhalt

  1. Konventionen, Darstellungsweisen, Operatoren
  2. Programmflusssteuerung, Anweisungen
  3. Fehlerbehandlung
  4. Einfache Datentypen
  5. Klassen, Interfaces, Adapter
  6. Modifizierer
  7. Packages
  8. Formatierung, Rundung
  9. Ausführbare .jar-Dateien
  10. SQL per JDBC
  11. Servlets, JavaServer Pages (JSP)
  12. JavaBean
  13. Enterprise JavaBean (EJB)
  14. Java Enterprise Edition (Java EE)
  15. RMI, RMI-IIOP, CORBA
  16. Weitere Java-Themen
  17. Links auf weiterführende Informationen


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).


Ausführbare .jar-Dateien

Die Klassen einer Java-Applikation können in eine einzelne .jar-Datei komprimiert werden. Das hat drei Vorteile: Erstens ist die Dateigröße kleiner, da komprimiert, zweitens werden bei einer Installation auf einem anderen Rechner keine Hilfsdateien vergessen, da alles in nur einer Datei ist und drittens kann das Betriebssystem so konfiguriert werden, dass .jar-Dateien genauso wie andere Executables auf Mausklick gestartet werden.
Für grafische Java-Applikationen, die (genauso wie übliche Windows-Programme) keine Ausgabe auf der System-Konsole machen, wird letzteres z.B. in Windows 2000 erreicht, indem im Windows-Explorer unter "Extras | Ordneroptionen | Dateitypen" mit "Neu" die Erweiterung "JAR" hinzugefügt wird und unter "Details für die Erweiterung 'JAR' | Erweitert | Bearbeiten" als "Vorgang" z.B. "Java Executable" und als "Anwendung für diesen Vorgang" z.B. "C:\Program Files\Java\jre6\bin\javaw.exe -jar %1" eingetragen wird (mit angepasstem Pfad zu javaw.exe).
Zusätzlich muss in dem .jar-Archive eine Manifest-Datei enthalten sein (z.B. mit Namen "MyProgr.mf"), aus der hervorgeht, welche Klasse die main-Methode enthält. Sie kann z.B. so aussehen:
Manifest-Version: 1.0
Main-Class: MyProgr
Das .jar-Archive kann z.B. mit folgendem Kommando erstellt werden:
jar cfm MyProgr.jar MyProgr.mf *.class *.jpg *.au


SQL per JDBC

SQL (Structured Query Language) ist die Abfragesprache für RDBMS (Relationales Datenbank-Management-System).
JDBC (Java DataBase Connectivity) ist die Java-Schnittstelle zu SQL-Datenbanken.
Weiteres hierzu siehe: java-sql.htm, jsp-grundlagen.htm, sql.htm, mysql.htm und postgresql.htm.


Servlets, JavaServer Pages (JSP)

Servlets und JavaServer Pages (JSP) sind Programmmodule zur Funktionserweiterung von HTTP-Servern zu Application Servern (entfernt vergleichbar mit CGI und MS-ASP).
Weiteres hierzu siehe: JSP und Webanwendungen.


JavaBean

JavaBeans sind Java-Komponenten. Sie bestehen aus einer Java-Klasse, die einen parameterlosen Konstruktor enthält, ihre Daten üblicherweise über getter- und setter-Methoden zugänglich macht (value=getAttr() bzw. setAttr(value)) und oft zusätzliche Methoden zur Ermittlung und Einstellung ihrer Eigenschaften anbietet (Introspection, Property Sheet, BDK).
Viele JavaBeans können als grafische Komponenten mit GUI-Editoren interaktiv zu Applikationen zusammengesetzt werden.
Andere JavaBeans haben keine sichtbare Oberfläche, z.B. wenn sie in JSPs verwendet werden.
JavaBeans können in einem Package zusammengefasst (package mypackage;) und zusammen mit einer Manifest-Datei in ein jar-Archiv gepackt werden:
javac -d ..\classes *.java
jar cfm MyBeans.jar Manifest.mf mypackage/*.class *.gif
Die Manifest-Datei Manifest.mf kann z.B. folgende Zeilen enthalten:
Name: mypackage/MyClass.class
Java-Bean: True
Werden mehrere .class-Dateien in eine .jar-Datei gepackt, werden diese Zeilen durch Leerzeilen getrennt für jede .class-Datei eingetragen.


Enterprise JavaBean (EJB)

Enterprise JavaBean ist eine Spezifikation zur Entwicklung und Verteilung von Komponenten-basierten verteilten Geschäftslogik-Anwendungen.
Wie JavaBeans sind auch Enterprise JavaBeans Programmmodule (Komponenten), aber sie sind für eine andere Umgebung bestimmt.
JavaBeans müssen nicht, aber können sichtbare GUI-Elemente sein, EJBs dagegen nie.
JavaBeans können von GUI-IDEs und RAD-Tools ausgewählt, inspiziert, konfiguriert, verknüpft und in Java-Programme eingebaut werden. Sie können von Java-Programmen einfach geladen und verwendet werden, sie werden wie andere Java-Klassen in der JVM ausgeführt.
EJBs dagegen sind gemanagte Objekte und benötigen eine spezielle Laufzeitumgebung (EJB-Container) in einem EJB-kompatiblen Java Application Server.
JavaBeans können ereignisgesteuert betrieben werden, während EJBs meistens über RMI-Aufrufe kommunizieren (Remote Method Invokation).
EJBs bedingen einen erhöhten Einarbeitungsaufwand, bieten dafür aber genau definierte Strukturen und Aufgabenteilungen. Diese Standardisierung erleichtert Komponenten-Verteilung, Skalierung, Load Balancing, Failover, Enterprise-Funktionen, Transaktionsmanagement und Sicherheitsmechanismen.
EJBs sind ein wichtiger Bestandteil von Java EE.
Weiteres siehe: jee-ejb2.htm und http://www.oracle.com/technetwork/java/javaee/ejb.


Java Enterprise Edition (Java EE)

Java EE (nicht zu verwechseln mit dem einfachen Java SE, der Java Standard Edition) bietet eine Framework-Architektur zur Entwicklung, Verteilung und Steuerung Server-seitiger verteilter mehrschichtiger (n-Tier) Geschäftslogik-Anwendungen.
Java EE beinhaltet folgende Schlüsseltechnologien:
Enterprise JavaBeans (EJB), Java Naming and Directory Interface (JNDI), Java Database Connenction (JDBC), Java Servlets, JavaServer Pages (JSP), Java Transaction API (JTA), Java Transaction Service (JTS), Java Messaging Service (JMS) und Remote Method Invocation (RMI).
Weiteres siehe: http://www.oracle.com/technetwork/java/javaee/overview, http://developer.java.sun.com/developer/onlineTraining/J2EE/Intro, http://www.jax.de/konferenzen/jax03/2003/stuff/SurvivingJ2EE.ppt und http://www.mobilexag.de/download/JUG_J2EE_Architektur.pdf.


RMI, RMI-IIOP, CORBA

Per RMI (Remote Method Invocation), RMI-IIOP (RMI over Internet Inter-ORB Protocol) und CORBA (Common Object Request Broker Architecture) können verteilte Komponenten kommunizieren. Weiterführende Links:
RMI: http://java.sun.com/products/jdk/rmi, http://developer.java.sun.com/developer/onlineTraining/rmi/RMI.html, http://www.jguru.com/jguru/faq/faqpage.jsp?name=RMI
RMI-IIOP: http://java.sun.com/products/rmi-iiop, http://docs.oracle.com/javase/7/docs/technotes/guides/rmi-iiop, http://www.javaworld.com/javaworld/jw-12-1999/jw-12-iiop.html
CORBA: http://www.corba.org, http://developer.java.sun.com/developer/onlineTraining/corba, http://www.jguru.com/jguru/faq/faqpage.jsp?name=CORBA




Weitere Themen: andere TechDocs | andere Java-Docs | Java-Installation | Java-Beispiele | JSP | SQL | Webanwendungen
© 1998-2007 Torsten Horn, Aachen