Java ist auch eine Insel - EDV

Werbung
Eines der traurigsten Dinge im Leben ist, dass ein Mensch viele gute Taten tun
muss, um zu beweisen, dass er tüchtig ist, aber nur einen Fehler zu begehen
braucht, um zu beweisen, dass er nichts taugt.
– George Bernard Shaw (1856 – 1950)
7
Angewandte Objektorientierung
7.1
Schnittstellen in der Anwendung
7.1.1
CharSequence als Beispiel einer Schnittstelle
Bisher kennen wir die Klassen String, StringBuffer und StringBuilder, um Zeichenketten
zu speichern und weiterzugeben. Ein String ist ein Wertobjekt und ein wichtiges Hilfsmittel
in Programmen, da durch ihn unveränderliche Zeichenkettenwerte repräsentiert werden,
während StringBuffer und StringBuilder veränderliche Zeichenfolgen umfassen. Aber wie
sieht es aus, wenn eine Teilzeichenkette gefordert ist, bei der es egal sein soll, ob das Original
als String-, StringBuffer oder StringBuilder-Objekt vorliegt?
Eine Lösung ist, alles in ein String-Objekt zu konvertieren. Möchte ein Programm eine Teilfolge liefern, auf die jemand lesend zugreifen möchte, die er aber nicht verändern können
soll, ist ein String zu träge. Aus den beliebigen Zeichenfolgen müsste zuerst ein StringObjekt konstruiert werden. Daher haben die Entwickler seit der Version 1.4 die Schnittstelle
CharSequence eingefügt, die eine unveränderliche, nur lesbare Sequenz von Zeichen realisiert. Die Schnittstelle implementieren die Klassen String sowie StringBuffer/StringBuilder. Funktionen müssen sich also nicht mehr für konkrete Klassen entscheiden, sondern können einfach ein CharSequence-Objekt als Argument akzeptieren oder als Rückgabe
weitergeben. Ein String und ein StringBuffer/StringBuilder-Objekt können zwar mehr,
als CharSequence vorschreibt, beide lassen sich aber als CharSequence einsetzen, wenn das
»Mehr« an Funktionalität nicht benötigt wird.
Abbildung 7.1
Einige implementierende Klassen für CharSequence
439
7
Angewandte Objektorientierung
interface java.lang.CharSequence
왘
char charAt( int index )
Liefert das Zeichen an der Stelle index.
왘
int length()
Gibt die Länge der Zeichensequenz zurück.
왘
CharSequence subSequence( int start, int end )
Liefert eine neue CharSequence von start bis end.
왘
String toString()
Gibt einen String der Sequenz zurück. Die Länge des toString()-Strings entspricht genau
der Länge der Sequenz.
Beispiel Soll eine Methode eine Zeichenkette bekommen und ist die Herkunft egal, so implementieren wir etwa:
void giveMeAText( CharSequence s )
{
...
}
anstatt der beiden Funktionen:
void giveMeAText( String s )
{
...
}
void giveMeAText( StringBuffer s )
{
void giveMeAText( new String(s) );
}
// oder Ähnliches
Anwendung von CharSequence in String
In den Klassen String und StringBuffer/StringBuilder existiert eine Methode subSequence(), die ein CharSequence-Objekt liefert. Die Signatur ist in beiden Fällen die gleiche.
Die Funktion macht im Prinzip nichts anderes als ein substring(begin, end).
class java.lang.String implements CharSequence, ...
class java.lang.StringBuffer implements CharSequence, ...
class java.lang.StringBuilder implements CharSequence, ...
왘
CharSequence subSequence( int beginIndex, int endIndex )
Liefert eine neue Zeichensequenz von String beziehungsweise StringBuffer.
Die Implementierung sieht so aus, dass mit substring() ein neuer Teilstring zurückgeliefert
wird. Das ist eine einfache Lösung, aber nicht unbedingt die schnellste. Für String-Objekte
440
Schnittstellen in der Anwendung
ist das Erzeugen von Substrings ziemlich schnell, da die Methode speziell optimiert ist. Da
Strings unveränderlich sind, wird einfach das gleiche char-Feld wie im Original-String verwendet, nur eine Verschiebung und ein Längenwert werden angepasst.
7.1.2
Die Schnittstelle Iterable
Die erweiterte for-Schleife läuft nicht nur Felder ab, sondern alles, was vom Typ Iterable ist.
Die Schnittstelle schreibt für Objekte nur eine Methode iterator() vor, die einen
java.util.Iterator liefert, den das for zum Durchlaufen verwendet.
interface java.lang.Iterable<T>
왘
Iterator<T> iterator()
Liefert einen Iterator, der über alle Elemente vom Typ T iteriert.
Viele Klassen implementieren schon diese Schnittstelle, sodass mit dem erweiterten for durch
Ergebnismengen iteriert werden kann. In erster Linie handelt es sich um Datenstrukturen.
Dazu kommt noch das Feld, das zwar nicht direkt als Klasse sichtbar ist, aber Iterable passend implementiert.
Einen eigenen Iterable implementieren
Möchten wir selbst rechts neben dem Doppelpunkt vom erweiterten for stehen, müssen wir
ein Objekt angeben, dessen Klasse Iterable implementiert und somit eine iterator()-Funktion besitzt. iterator() muss dann einen passenden Iterator zurückgeben. Der wiederum
muss die Methoden hasNext() und next() implementieren, um das nächste Element in der
Aufzählung anzugeben und das Ende anzuzeigen. Zwar schreibt der Iterator auch remove()
vor, doch das wird leer implementiert.
Unser Beispiel soll einen praktischen Iterable implementieren, um über Wörter eines Satzes
zu gehen. Als grundlegende Implementierung dient der StringTokenizer, der über hasToken() die nächsten Teilfolgen und über hasMoreTokens() meldet, ob weitere Tokens ausgelesen werden können.
Beginnen wir mit dem ersten Teil, der Klasse WordIterable, die erst einmal Iterable implementieren muss, um auf der rechten Seite vom Punkt stehen zu können. Dann muss dieses
Exemplar über iterator() einen Iterator zurückgeben, der über alle Wörter läuft. Dieser
Iterator kann als eigene Klasse implementiert werden, doch wir implementieren die Klasse
WordIterable so, dass sie Iterable und Iterator gleichzeitig verkörpert; daher ist nur ein
Exemplar nötig.
441
7.1
7
Angewandte Objektorientierung
Listing 7.1
com/tutego/insel/iterable/WordIterable.java
package com.tutego.insel.iterable;
import java.util.*;
class WordIterable implements Iterable<String>, Iterator<String>
{
private StringTokenizer st;
public WordIterable( String s )
{
st = new StringTokenizer( s );
}
// Method from interface Iterable
@Override public Iterator<String> iterator()
{
return this;
}
// Methods from interface Iterator
@Override public boolean hasNext()
{
return st.hasMoreTokens();
}
@Override public String next()
{
return st.nextToken();
}
@Override public void remove()
{
// No remove.
}
}
Im Beispiel:
Listing 7.2 com/tutego/insel/iterable/WordIterableDemo.java, main()
String s = "Am Anfang war das Wort – am Ende die Phrase. (Stanislaw Jerzy Lec)";
for ( String word : new WordIterable(s) )
System.out.println( word );
442
Schnittstellen in der Anwendung
Die erweiterte for-Schleife baut der (Eclipse-)Compiler um zu:
Object word;
WordIterable worditerable;
for ( Iterator iterator = (worditerable = new WordIterable(s)).iterator();
iterator.hasNext(); )
{
word = iterator.next();
System.out.println( word );
}
7.1.3
Funktionszeiger
Das folgende Beispiel implementiert Funktionszeiger über Schnittstellen. Es beginnt mit der
Markierungsschnittstelle Operator.
Listing 7.3
com/tutego/insel/functions/Operator.java
package com.tutego.insel.functions;
public interface Operator
{
// Markierungsschnittstelle
}
Sie soll Basis-Schnittstelle für Operatoren sein. Von dieser Schnittstelle wollen wir BinaryOperator ableiten, eine Schnittstelle mit einer Operation für zweistellige Operatoren.
Listing 7.4
com/tutego/insel/functions/BinaryOperator.java
package com.tutego.insel.functions;
public interface BinaryOperator extends Operator
{
double calc( double a, double b );
}
Zum Test sollen die Operatoren für + und * implementiert werden:
Listing 7.5
com/tutego/insel/functions/MulOperator.java
package com.tutego.insel.functions;
public class MulOperator implements BinaryOperator
{
public double calc( double a, double b )
{
return a * b;
}
}
443
7.1
7
Angewandte Objektorientierung
Listing 7.6 com/tutego/insel/functions/AddOperator.java
package com.tutego.insel.functions;
public class AddOperator implements BinaryOperator
{
public double calc( double a, double b )
{
return a + b;
}
}
Eine Sammlung von Operatoren speichert ein Operator-Manager. Bei ihm können wir dann
über eine Kennung ein Berechnungsobjekt beziehen:
Listing 7.7
com/tutego/insel/functions/OperatorManager.java
package com.tutego.insel.functions;
public class OperatorManager
{
public final static int ADD = 0;
public final static int MUL = 1;
private static Operator[] operators = {
new AddOperator(),
new MulOperator()
};
public static Operator getOperator( int id )
{
return operators[ id ];
}
}
Wenn wir nun einen Operator wünschen, so fragen wir den OperatorManager nach dem passenden Objekt. Die Rückgabe wird ein Operator-Objekt sein, was wir auf BinaryOperator
anpassen, da der Basistyp keine Funktionalität ermöglicht. Dann können wir die Funktion
calc() aufrufen:
BinaryOperator op = (BinaryOperator) OperatorManager.getOperator(OperatorManager.ð
ADD);
System.out.println( op.calc( 12, 34 ) );
So verbirgt sich hinter jeder ID eine Funktion, die wie ein Funktionszeiger verwendet werden
kann. Noch interessanter ist es, die Funktionen in einen Assoziativspeicher einzusetzen und
dann über einen Namen zu erfragen. Diese Implementierung nutzt kein Feld, sondern eine
Datenstruktur Map. Eine Erweiterung der Idee nutzt dann auch gleich Enums und EnumMap zur
Assoziation zwischen Aufzählung und Funktion.
444
Schnittstellen in der Anwendung
7.1.4
Implementierung einer verketteten Liste
Verkettete Listen gibt es in Java seit Java 1.2 über die Klasse LinkedList, sodass wir die Implementierung eigentlich nicht betrachten müssten. Da es für viele Leser jedoch noch ein
Geheimnis ist, wie die dazu benötigten Pointer in Java abgebildet werden, sehen wir uns eine
einfache Implementierung an. Zunächst benötigen wir eine Zelle, die Daten und eine Referenz
auf das folgende Listenelement speichert. Die Zelle wird durch die Klasse Cell modelliert. Im
UML-Diagramm taucht die innere Klasse im letzten Block auf.
Listing 7.8
com/tutego/insel/list/LinkedList.java
package com.tutego.insel.list;
public class LinkedList
{
private Cell head, tail;
static class Cell
{
Object data;
Cell
next;
}
public void add( Object o )
{
Cell newCell = new Cell();
newCell.data = o;
if ( head == null )
head = tail = newCell;
else
tail = tail.next = newCell;
// or tail == null
}
public void addAll( Object... os )
{
for ( Object o : os )
add( o );
}
445
7.1
7
Angewandte Objektorientierung
@Override
public String toString()
{
StringBuilder sb = new StringBuilder( 1024 ).append( '[' );
for ( Cell cell = head; cell != null; )
{
sb.append( cell.data );
if ( cell.next != null )
sb.append( ", " );
cell = cell.next;
}
return sb.append( ']' ).toString();
}
}
Eine verkettete Liste besteht aus einer Menge von Cell-Elementen. Da diese Objekte fest mit
der Liste verbunden sind, ist hier der Einsatz von geschachtelten Klassen sinnvoll. Cell ist hier
statisch, kann aber auch Elementklasse sein, doch ist das egal, weil die Klasse von außen nicht
sichtbar ist.
Die Liste benötigt zum Einfügen einen Verweis auf den Kopf (erstes Element) und auf das
Ende (letztes Element). Um nun ein Element dieser Liste hinzuzufügen, erzeugen wir zunächst
eine neue Zelle newCell. Ist tail oder head gleich null, bedeutet dies, dass es noch keine Elemente in der Liste gibt. Danach legen wir die Referenzen für Listenanfang und -ende auf das
neue Objekt. Werden nun später Elemente eingefügt, hängen sie sich hinter tail. Wenn es
schon Elemente in der Liste gibt, dann ist head oder tail nicht gleich null, und tail zeigt auf
das letzte Element. Seine next-Referenz zeigt auf null und wird dann mit einem neuen Wert
belegt, nämlich mit dem des neu beschafften Objekts newCell. Nun hängt es in der Liste, und
das Ende muss noch angepasst werden. Daher legen wir die Referenz tail auch noch auf das
neue Objekt.
Listing 7.9
com/tutego/insel/list/LinkedListDemo.java, main()
LinkedList l = new LinkedList();
l.addAll( "Hallo", "Otto" );
7.2
Design-Pattern (Entwurfsmuster)
Aus dem objektorientierten Design haben wir gelernt, dass Klassen nicht fest miteinander verzahnt, sondern lose gekoppelt sein sollen. Das bedeutet: Klassen sollten nicht zu viel über
andere Klassen wissen, und die Interaktion soll über wohldefinierte Schnittstellen erfolgen,
sodass die Klassen später noch verändert werden können. Die lose Kopplung hat viele Vor-
446
Design-Pattern (Entwurfsmuster)
teile, da so die Wiederverwendung erhöht und das Programm änderungsfreundlicher wird.
Wir wollen dies an einem Beispiel prüfen:
In einer Datenstruktur sollen Kundendaten gespeichert werden. Zu dieser Datenquelle gibt es
eine grafische Oberfläche, die diese Daten anzeigt und verwaltet, etwa eine Eingabemaske.
Wenn Daten eingegeben, gelöscht und verändert werden, sollen sie in die Datenstruktur
übernommen werden. Den anderen Weg von der Datenstruktur in die Visualisierung werden
wir gleich beleuchten. Bereits jetzt haben wir eine Verbindung zwischen Eingabemaske und
Datenstruktur, und wir müssen aufpassen, dass wir uns im Design nicht verzetteln, denn vermutlich läuft die Programmierung darauf hinaus, dass beide fest miteinander verbunden sind.
Wahrscheinlich wird die grafische Oberfläche irgendwie über die Datenstruktur Bescheid wissen, und bei jeder Änderung in der Eingabemaske werden direkt Methoden der konkreten
Datenstruktur aufgerufen. Das wollen wir vermeiden. Genauso haben wir nicht bedacht, was
passiert, wenn nun in Folge weiterer Programmversionen eine grafische Repräsentation der
Daten etwa in Form eines Balkendiagramms gezeichnet wird. Und was geschieht, wenn der
Inhalt der Datenstruktur über andere Programmfunktionen geändert wird und dann einen
Neuaufbau der Bildschirmdarstellung erzwingt? Hier verfangen wir uns in einem Knäuel von
Methodenaufrufen, und änderungsfreundlich ist dies dann auch nicht mehr. Was ist, wenn
wir nun unsere selbst gestrickte Datenstruktur durch eine SQL-Datenbank ersetzen wollen?
7.2.1
Design-Pattern
Wir sind nicht die Ersten, die sich über grundlegende Design-Kriterien Gedanken machen.
Vor dem objektorientierten Programmieren (OOP) gab es das strukturierte Programmieren,
und die Entwickler waren froh, mit Werkzeugen schneller und einfacher Software bauen zu
können. Auch die Assembler-Programmierer waren erfreut, strukturiertes Programmieren zur
Effizienzsteigerung einsetzen zu können – sie haben ja auch Unterprogramme nur deswegen
eingesetzt, weil sich mit ihnen wieder ein paar Bytes sparen ließen. Doch nach Assembler und
strukturiertem Programmieren sind wir nun bei der Objektorientierung angelangt, und
dahinter zeichnet sich bisher kein revolutionäres Programmierparadigma ab. Die Softwarekrise hat zu neuen Konzepten geführt, doch merkt fast jedes Entwicklungsteam, dass OO nicht
alles ist, sondern nur ein verwunderter Ausspruch nach drei Jahren Entwicklungsarbeit an
einem schönen Finanzprogramm: »Oh, oh, alles Mist.« So schön OO auch ist, wenn sich 10
000 Klassen im Klassendiagramm tummeln, ist das genauso unübersichtlich wie ein
FORTRAN-Programm mit 10 000 Zeilen. Da in der Vergangenheit oft gutes Design für ein
paar Millisekunden Laufzeit geopfert wurde, ist es nicht verwunderlich, dass Programme
nicht mehr lesbar sind. Doch wie am Beispiel vom Satzprogramm TeX (etwa 1985) zu sehen
ist: Code lebt länger als Hardware, und die nächste Generation von Mehr-Kern-Prozessoren
wird sich bald in unseren Desktop-PCs nach Arbeit sehnen.
Es fehlt demnach eine Ebene über den einzelnen Klassen und Objekten, denn die Objekte
selbst sind nicht das Problem, vielmehr ist es die Kopplung. Hier helfen Regeln weiter, die
unter dem Stichwort Entwurfsmuster (engl. design pattern) bekannt geworden sind. Dies sind
Tipps von Softwaredesignern, denen aufgefallen ist, dass viele Probleme auf ähnliche Weise
447
7.2
7
Angewandte Objektorientierung
gelöst werden können. Sie stellten daher Regelwerke mit Lösungsmustern auf, die eine optimale Wiederverwendung von Bausteinen und Änderungsfreundlichkeit aufweisen. DesignPattern ziehen sich durch die ganze Java-Klassenbibliothek, und die bekanntesten sind Beobachter (Observer)-Pattern, Singleton, Fabrik (Factory) und Composite; die Fabrik und das Singleton haben wir bereits kennengelernt.
7.2.2
Das Beobachter-Pattern (Observer/Observable)
Wir wollen uns nun mit dem Observer-Pattern beschäftigen, das seine Ursprünge in Smalltalk-80 hat. Dort ist es etwas erweitert unter dem Namen MVC (Model-View-Controller)
bekannt, ein Kürzel, mit dem auch wir uns noch näher beschäftigen müssen, da dies ein ganz
wesentliches Konzept bei der Programmierung grafischer Bedieneroberflächen mit Swing ist.
Stellen wir uns eine Party mit einer netten Gesellschaft vor. Hier finden sich zurückhaltende
passive Gäste und aktive Erzähler. Die Zuhörer sind interessiert an den Gesprächen der Unterhalter. Da die Erzähler nun von den Zuhörern beobachtet werden, bekommen sie den Namen
Beobachtete, auf Englisch auch Observables (Beobachtbare) genannt. Die Erzähler interessieren sich jedoch nicht dafür, wer ihnen zuhört. Für sie sind alle Zuhörer gleich. Sie schweigen
jedoch, wenn ihnen überhaupt niemand zuhört. Die Zuhörer reagieren auf Witze der Unterhalter und werden dadurch zu Beobachtern (engl. observers).
Die Klasse Observable und die Schnittstelle Observer
Unser Beispiel mit den Erzählern und Zuhörern können wir auf Datenstrukturen übertragen.
Die Datenstruktur lässt sich beobachten und wird zum Beobachteten. Sie wird in Java als
Exemplar der Bibliotheksklasse Observable repräsentiert. Der Beobachter wird durch die
Schnittstelle Observer abgedeckt und ist der, der informiert werden will, wenn sich die
Datenstruktur ändert. Jedes Exemplar der Observable-Klasse informiert nun alle seine Horcher, wenn sich sein Zustand ändert. Denken wir wieder an unser ursprüngliches Beispiel mit
der Visualisierung. Wenn wir nun zwei Sichten auf die Datenstruktur haben, etwa die Eingabemaske und ein Balkendiagramm, ist es der Datenstruktur egal, wer an den Änderungen
interessiert ist. Ein anderes Beispiel: Die Datenstruktur enthält einen Wert, der durch einen
Schieberegler und ein Textfeld angezeigt wird. Beide Bedienelemente wollen informiert werden, wenn sich dieser Wert ändert. Es gibt viele Beispiele für diese Konstellation, sodass die
Java-Entwickler die Klasse Observable und die Schnittstelle Observer mit in die Standardbibliothek aufgenommen haben. Noch besser wäre die Entscheidung gewesen, die Funktionalität in die oberste Klasse Object aufzunehmen, so wie es Smalltalk macht.
Die Klasse Observable
Eine Klasse, deren Exemplare sich beobachten lassen, muss jede Änderung des Objektzustands nach außen hin mitteilen. Dazu bietet die Klasse Observable die Methoden setChanged() und notifyObservers() an. Mit setChanged() wird die Änderung angekündigt, und
mit notifyObservers() wird sie tatsächlich übermittelt. Gibt es keine Änderung, so wird
notifyObservers() auch niemanden benachrichtigen.
448
Design-Pattern (Entwurfsmuster)
Wir wollen nun das Party-Szenario in Java implementieren. Dazu schreiben wir eine Klasse
JokeTeller, deren Objekte einen Witz erzählen können. Sie machen mit setChanged() auf
eine Änderung ihres Zustands aufmerksam und versorgen dann mit notifyObservers() die
Zuhörer mit dem Witz in Form einer Zeichenkette.
Listing 7.10
com/tutego/insel/pattern/observer/JokeTeller.java
package com.tutego.insel.ds.observer;
import java.util.*;
class JokeTeller extends Observable
{
private static final List<String> jokes = Arrays.asList(
"Sorry, aber du siehst so aus, wie ich mich fühle.",
"Eine Null kann ein bestehendes Problem verzehnfachen.",
"Wer zuletzt lacht, hat es nicht eher begriffen.",
"Wer zuletzt lacht, stirbt wenigstens fröhlich.",
"Unsere Luft hat einen Vorteil: Man sieht, was man einatmet."
);
public void tellJoke()
{
setChanged();
Collections.shuffle( jokes );
notifyObservers( jokes.get(0) );
}
}
setChanged() setzt intern ein Flag, das von notifyObservers() abgefragt wird. Nach dem
Aufruf von notifyObservers() wird dieses Flag wieder gelöscht. Dies kann auch manuell mit
clearChanged() geschehen. notifyObservers() sendet nur dann eine Benachrichtigung an
die Zuhörer, wenn auch das Flag gesetzt ist. So kommen folgende Programmzeilen häufig
zusammen vor, da sie das Flag setzen und alle Zuhörer informieren.
setChanged();
notifyObservers( Object );
// Eine Änderung ist aufgetreten
// Informiere Observer über Änderung
Die notifyObservers()-Methode existiert auch ohne extra Parameter. Sie entspricht einem
notifyObservers(null). Mit der Methode hasChanged() können wir herausfinden, ob das
Flag der Änderung gesetzt ist.
449
7.2
7
Angewandte Objektorientierung
Interessierte Beobachter müssen sich am Observable-Objekt mit der Methode addObserver(Observer) anmelden. Dabei sind aber keine beliebigen Objekte als Beobachter erlaubt,
sondern nur solche, die die Schnittstelle Observer implementieren. Sie können sich mit
deleteObserver(Observer) wieder abmelden. Die Anzahl der angemeldeten Observer teilt
uns countObservers() mit. Leider ist die Namensgebung etwas unglücklich, da Klassen mit
der Endung »able« eigentlich immer Schnittstellen sein sollten. Genau das ist hier aber nicht
der Fall. Der Name Observer bezeichnet überraschenderweise eine Schnittstelle, und hinter
dem Namen Observable verbirgt sich eine echte Klasse.
Die Schnittstelle Observer
Das aktive Objekt, der Sender der Nachrichten, ist ein Exemplar der Klasse Observable, das
Benachrichtigungen an angemeldete Objekte schickt. Das aktive Objekt informiert alle zuhörenden Objekte, die die Schnittstelle Observer implementieren müssen.
Jetzt können wir für die Party auch die Zuhörer implementieren.
Listing 7.11 com/tutego/insel/pattern/observer/JokeListener.java
class JokeListener implements Observer
{
final private String name;
JokeListener( String name )
{
this.name = name;
}
public void update( Observable o, Object arg )
{
System.out.println( name + " lacht über: \"" + arg + "\"" );
}
}
interface java.util.Observer
왘
void update( Observable o, Object arg )
Wird bei Benachrichtigungen vom Observable o aufgerufen. Als zweites Argument trifft
die über notifyObservers(Object) verschickte Nachricht ein. Bei der parameterlosen
Variante notifyObservers() ist der aktuelle Parameter null.
Da auf einer echten Party die Zuhörer und Erzähler nicht fehlen dürfen, baut die dritte Klasse
Party nun echte Stimmung auf.
Listing 7.12 com/tutego/insel/pattern/observer/Party.java
package com.tutego.insel.ds.observer;
import java.util.*;
450
Design-Pattern (Entwurfsmuster)
public class Party
{
public static void main( String[] args )
{
Observer achim
= new JokeListener( "Achim" );
Observer michael = new JokeListener( "Michael" );
JokeTeller chris = new JokeTeller();
chris.addObserver( achim );
chris.tellJoke();
chris.tellJoke();
chris.addObserver( michael );
chris.tellJoke();
chris.deleteObserver( achim );
chris.tellJoke();
}
}
Wir melden zwei Zuhörer nacheinander an und einen wieder ab. Dann geht das Lachen los.
7.2.3
Ereignisse über Listener
Eine Erweiterung der Möglichkeiten über Observer/Observable sind Listener. Es gibt Ereignisauslöser, die spezielle Ereignis-Objekte aussenden, und Interessenten, die sich bei den Auslösern an- und abmelden – sie werden in Java Listener genannt. Die beteiligten Klassen und
Schnittstellen folgen einer bestimmten Namenskonvention; XXX steht im Folgenden stellvertretend für einen Ereignisnamen.
Eine Klasse für die Ereignisobjekte heißt XXXEvent. Die Ereignisobjekte können Informationen wie Auslöser, Zeitstempel und weitere Daten speichern.
Die Interessenten implementieren als Listener eine Java-Schnittstelle, die XXXListener heißt.
Die Operation der Schnittstelle kann beliebig lauten, doch wird ihr üblicherweise das XXXEvent übergeben. Anders als beim Observer/Observable kann diese Schnittstelle auch mehrere Operationen vorschreiben.
Der Ereignisauslöser bietet Methoden addXXXListener(XXXListener) und removeXXXListener(XXXListener) an, um Interessenten an- und abzumelden. Immer wenn ein Ereignis stattfindet, erzeugt der Auslöser das Ereignisobjekt XXXEvent und informiert jeden Listener, der in
der Liste eingetragen ist, über einen Aufruf der Methode aus dem Listener.
Die beteiligten Typen soll ein Beispiel verdeutlichen.
451
7.2
7
Angewandte Objektorientierung
Radios spielen Werbung
Ein Radio soll für Werbungen AdEvent-Objekte aussenden. Die Ereignis-Objekte sollen den
Werbespruch (Slogan) speichern.
Listing 7.13
com/tutego/insel/pattern/listener/AdEvent.java
package com.tutego.insel.pattern.listener;
import java.util.EventObject;
public class AdEvent extends EventObject
{
private String slogan;
public AdEvent( Object source, String slogan )
{
super( source );
this.slogan = slogan;
}
public String getSlogan()
{
return slogan;
}
}
Die Klasse AdEvent erweitert EventObject, eine Klasse, die alle Ereignis-Klassen erweitern.
Der parametrisierte Konstruktor von AdEvent nimmt im ersten Parameter den Ereignisauslöser an und gibt ihn mit super(source) an den Konstruktor der Oberklasse weiter, der ihn
speichert und mit getSource() wieder verfügbar macht. Der zweite Parameter vom AdEventKonstruktor ist unsere Werbung.
Der AdListener ist die Schnittstelle, die Interessenten implementieren:
Listing 7.14
com/tutego/insel/pattern/listener/AdListener.java
package com.tutego.insel.pattern.listener;
import java.util.EventListener;
/** The listener interface for receiving ad events. */
interface AdListener extends EventListener
{
/** Invoked when an ad occurs. */
void advertisement( AdEvent e );
}
Unser AdListener implementiert die Schnittstelle EventListener (eine Markierungsschnittstelle), die alle Java-Listener implementieren sollen. Wir schreiben für konkrete Listener nur
eine Operation advertisement() vor.
452
Design-Pattern (Entwurfsmuster)
Das Radio soll nun Interessenten an- und abmelden können. Es sendet über einen Timer Werbenachrichten. Das Spannende an der Implementierung ist die Tatsache, dass die Listener
nicht in einer eigenen Datenstruktur verwaltet werden, sondern eine spezielle Listener-Klasse
aus dem Swing-Paket verwendet wird.
Listing 7.15
com/tutego/insel/pattern/listener/Radio.java
package com.tutego.insel.pattern.listener;
import java.util.*;
import javax.swing.event.EventListenerList;
public class Radio
{
/** List of listeners. */
private EventListenerList listeners = new EventListenerList();
/** All advertisements. */
private List<String> ads = Arrays.asList( "Jetzt explodiert auch der Haarknoten",
"Red Fish verleiht Flossen",
"Bom Chia Wowo",
"Wunder Whip. Iss milder." );
/** Radio with frequent ads. */
public Radio()
{
new Timer().schedule( new TimerTask()
{
@Override public void run()
{
Collections.shuffle( ads );
notifyAdvertisement( new AdEvent( this, ads.get(0) ) );
}
}, 0, 500 );
}
/**
* Adds an {@code AdListener} to the radio.
* @param l the {@code AdListener} to be added
*/
public void addAdListener( AdListener listener )
{
listeners.add( AdListener.class, listener );
}
/**
* Removes an {@code AdListener} from the radio.
* @param l the listener to be removed
*/
453
7.2
7
Angewandte Objektorientierung
public void removeAdListener( AdListener listener )
{
listeners.remove( AdListener.class, listener );
}
/**
* Notifies all {@code AdListener}s that have registered interest for
* notification on an {@code AdEvent}.
* @param event the {@code AdEvent} object
* @see EventListenerList
*/
protected synchronized void notifyAdvertisement( AdEvent event )
{
for ( AdListener l : listeners.getListeners( AdListener.class ) )
l.advertisement( event );
}
}
Die Demo-Anwendung nutzt das Radio-Objekt und implementiert einen konkreten Listener.
package com.tutego.insel.pattern.listener;
public class RadioDemo
{
public static void main( String args[] )
{
Radio r = new Radio();
class ComplainingAdListener implements AdListener {
public void advertisement( AdEvent e ) {
System.out.println( "Oh nein, schon wieder Werbung: " + e.getSlogan() );
}
}
r.addAdListener( new ComplainingAdListener() );
}
}
7.2.4
Multicast und Unicast
Normalerweise können mit einem Auslöser beliebig viele Zuhörer verbunden werden. Tritt
ein Ereignis auf, dann informiert die Komponente alle Interessierten. Das ist Multicast. Eine
Einschränkung davon ist Unicast, bei dem sich nur ein Interessent anmelden darf. Versucht es
ein zweiter, wird eine Ausnahme ausgelöst. Erlaubt die add-Methode nur einen Listener, weil
sie nur Unicast gestattet, so kann sie eine java.util.TooManyListenersException auslösen.
454
JavaBean
7.3
JavaBean
Unter der JavaBean-Architektur versteht Sun ein einfaches Komponenten-Modell. Beans
kommen in allen Ecken der Java-Bibliothek vor, in grafischen Oberflächen, bei Servlets, bei
der Persistenz (Abbildung der Objekte in relationale Datenbanken oder XML-Dokumenten),
und weiteren Einsatzgebieten. Im Kern basieren JavaBeans auf:
왘
Selbstbeobachtung (Introspection). Eine Klasse lässt sich von außen auslesen. So kann ein
spezielles Programm, wie ein GUI-Builder oder eine visuelle Entwicklungsumgebung, eine
Bean analysieren und ihre Eigenschaften abfragen. Auch umgekehrt kann eine Bean herausfinden, ob sie etwa gerade von einem grafischen Entwicklungswerkzeug modelliert
wird oder in einer Applikation ohne GUI Verwendung findet.
왘
Eigenschaften (Properties). Attribute beschreiben den Zustand des Objekts. In einem
Modellierungswerkzeug lassen sich diese ändern. Da eine Bean zum Beispiel eine grafische
Komponente sein kann, hat sie etwa eine Hintergrundfarbe. Diese Informationen können
von außen durch bestimmte Methoden abgefragt und verändert werden. Für alle Eigenschaften werden spezielle Zugriffsmethoden definiert; sie werden Property-Design-Pattern
genannt.
왘
Ereignissen (Events). Komponenten können Ereignisse auslösen, die Zustandsänderungen
oder Programmteile weiterleiten können.
왘
Anpassung (Customization). Der Bean-Entwickler kann die Eigenschaften einer Bean
visuell und interaktiv anpassen.
왘
Speicherung (Persistenz). Jede Bean kann ihren internen Zustand, also die Eigenschaften,
durch Serialisierung speichern und wiederherstellen. So kann ein Builder-Tool die Komponenten laden und benutzen. Ein spezieller Externalisierungsmechanismus erlaubt dem
Entwickler die Definition eines eigenen Speicherformats, zum Beispiel als XML-Datei.
Zusätzlich zu diesen notwendigen Grundpfeilern lässt sich durch Internationalisierung die
Entwicklung internationaler Komponenten vereinfachen. Verwendet eine Bean länderspezifische Ausdrücke wie Währungsformate oder Datumsformate, kann der Bean-Entwickler mit
länderunabhängigen Bezeichnern arbeiten, die dann in die jeweilige Landessprache übersetzt
werden.
7.3.1
Properties (Eigenschaften)
Properties einer JavaBean steuern den Zustand des Objektes. Bisher hat Java keine spezielle
Schreibweise für Properties – anders als C# und andere Sprachen –, und so nutzt es eine spezielle Namensgebung bei den Methoden, um Eigenschaften zu lesen und zu schreiben. Der
JavaBeans-Standard unterscheidet vier Arten von Properties:
왘
Einfache Eigenschaften. Hat eine Person eine Property »Name« , so bietet die JavaBean die
Methoden getName() und setName() an.
455
7.3
7
Angewandte Objektorientierung
왘
Indizierte/Indexierte Eigenschaften (engl. indexed properties). Sie werden eingesetzt,
falls mehrere gleiche Eigenschaften aus einem Array verwaltet werden. So lassen sich Felder gleichen Datentyps verwalten.
왘
Gebundene Eigenschaften (engl. bound properties). Ändert eine Komponente ihr Verhalten, dann kann sie angemeldete Interessenten (Listener) informieren.
왘
Eigenschaft mit Vetorecht (engl. veto properties, auch constraint properties beziehungsweise eingeschränkte Eigenschaften genannt). Ihre Benutzung ist in jenen Fällen angebracht, in denen eine Bean Eigenschaften ändern möchte, andere Beans aber dagegen sind
und ihr Veto einlegen.
Die Eigenschaften der Komponente können primitive Datentypen, aber auch komplexe Klassen sein. Der Text einer Schaltfläche ist ein einfacher String, eine Sortierstrategie in einem
Sortierprogramm ist jedoch ein komplexes Objekt.
7.3.2
Einfache Eigenschaften
Für die einfachen Eigenschaften müssen nur ein Paar von setXXX()- und getXXX()-Methoden
eingesetzt werden. Der Zugriff auf eine Objektvariable wird also über Funktionen geregelt.
Dies hat den Vorteil, dass ein Zugriffsschutz und weitere Überprüfungen eingerichtet werden
können. Soll eine Eigenschaft nur gelesen werden (weil sie sich zum Beispiel regelmäßig automatisch aktualisiert), müssen wir die setXXX()-Methode nicht implementieren. Genauso gut
können wir Werte, die außerhalb des erlaubten Wertebereichs unserer Applikation liegen,
prüfen und ablehnen. Dazu kann eine Methode eine Exception auslösen.
Allgemein sieht dann die Signatur der Methoden für eine Eigenschaft XXX vom Typ T folgendermaßen aus:
왘
public T getXXX()
왘
public void setXXX( T value )
Ist der Property-Typ ein Wahrheitswert, ist neben der Methode getXXX() eine isXXX()Methode erlaubt.
왘
public boolean isXXX()
왘
public void setXXX( boolean value )
7.3.3
Indizierte Eigenschaften
Falls eine Bean nur über eine einfache Eigenschaft wie eine primitive Variable verfügt, so weisen die getXXX()-Methoden keinen Parameter und genau einen Rückgabewert auf. Der Rückgabewert hat den gleichen Datentyp wie die interne Eigenschaft. Die setXXX()-Methode
besitzt genau einen Parameter des Datentyps dieser Eigenschaft. Eine setXXX()-Methode hat
keinen expliziten Rückgabewert. Wenn nun kein atomarer Wert, sondern ein Feld von Werten intern gespeichert ist, müssen wir Zugriff auf bestimmte Werte bekommen. Daher erwarten die setXXX()- und getXXX()-Methoden im zusätzlichen Parameter einen Index:
456
JavaBean
왘
public T[] getXXX()
왘
public T getXXX( int index )
왘
public void setXXX( T[] values )
왘
public void setXXX( T value, int index )
7.3.4
Gebundene Eigenschaften
Die gebundenen Eigenschaften einer Bean erlauben es, andere Komponenten über eine
Zustandsänderung der Properties zu informieren. Bei den gebundenen Eigenschaften (engl.
bound properties) geht es ausschließlich um Änderungen der Properties und nicht um andere
Ereignisse, die nicht mit den Bean-Eigenschaften zu tun haben.
Die Listener empfangen von der Bean ein PropertyChangeEvent, das sie auswerten können.
Die Interessenten lassen sich mit addPropertyChangeListener() als Zuhörer einfügen und
mit removePropertyChangeListener() abhängen. Bei einer Veränderung werden alle registrierten Zuhörer durch ein PropertyChangeEvent informiert. Die Interessierten implementieren dafür PropertyChangeListener. Das Ereignis-Objekt speichert den alten und den neuen
Wert sowie den Typ und den Namen der Eigenschaft. Die Zuhörer werden erst nach der
Änderung des internen Zustands informiert.
Ein Beispiel: Unsere Person-Komponente besitzt eine Property »Name«, die der Setter setName() ändert. Nach der Änderung werden alle Listener informiert. Sie bewirkt sonst nichts
Großartiges.
Listing 7.16
com/tutego/insel/bean/bound/Person.java
package com.tutego.insel.bean.bound;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Person
{
private String name = "";
private PropertyChangeSupport changes = new PropertyChangeSupport( this );
public void setName( String name )
{
String oldName = this.name;
this.name = name;
changes.firePropertyChange( "name", oldName, name );
}
public String getName()
{
return name;
}
457
7.3
7
Angewandte Objektorientierung
public void addPropertyChangeListener( PropertyChangeListener l )
{
changes.addPropertyChangeListener( l );
}
public void removePropertyChangeListener( PropertyChangeListener l )
{
changes.removePropertyChangeListener( l );
}
}
Der Implementierung setName() kommt zentrale Bedeutung zu. Der erste Parameter von
firePropertyChange() ist der Name der Eigenschaft. Er ist für das Ereignis von Belang und
muss nicht zwingend der Name der Bean-Eigenschaft sein. Es folgen der alte und der neue
Stand des Werts. Die Methode informiert alle angemeldeten Zuhörer über die Änderung mit
einem PropertyChangeEvent.
class java.beans.PropertyChangeSupport
implements Serializable
왘
PropertyChangeSupport( Object sourceBean )
Konstruiert ein PropertyChangeSupport-Objekt, das sourceBean als auslösende Bean
betrachtet.
왘
synchronized void addPropertyChangeListener( PropertyChangeListener listener )
Fügt einen Listener hinzu.
왘
synchronized void removePropertyChangeListener( PropertyChangeListener listener )
Entfernt einen Listener.
왘
synchronized void addPropertyChangeListener( String propertyName,
PropertyChangeListener listener )
Fügt einen Listener hinzu, der nur auf Ereignisse mit dem Namen propertyName hört.
왘
synchronized void removePropertyChangeListener( String propertyName,
PropertyChangeListener listener )
Entfernt den Listener, der auf propertyName hört.
왘
void firePropertyChange( String propertyName, Object oldValue, Object newValue )
Informiert alle Listener über eine Werteänderung. Sind alte und neue Werte gleich, werden keine Events ausgelöst.
왘
void firePropertyChange( String propertyName, int oldValue, int newValue )
void firePropertyChange( String propertyName, boolean oldValue, boolean newValue )
Varianten von firePropertyChange() mit Integer- und Boolean-Werten.
왘
void firePropertyChange( PropertyChangeEvent evt )
Informiert alle Interessenten mit einem PropertyChangeEvent, indem es propertyChange() aufruft.
왘
synchronized boolean hasListeners( String propertyName )
Liefert true, wenn es mindestens einen Listener für die Eigenschaft gibt.
458
JavaBean
Angemeldete PropertyChangeListener können auf das PropertyChangeEvent reagieren. Wir
testen das an einer Person, die einen neuen Namen bekommt.
Listing 7.17
com/tutego/insel/bean/bound/PersonWatcher.java, main()
Person p = new Person();
p.addPropertyChangeListener( new PropertyChangeListener()
{
@Override public void propertyChange( PropertyChangeEvent e )
{
System.out.printf( "Property '%s': '%s' -> '%s'%n",
e.getPropertyName(), e.getOldValue(), e.getNewValue() );
}
} );
p.setName( "Ulli" );
// Property 'name': '' -> 'Ulli'
p.setName( "Ulli" );
p.setName( "Chris" ); // Property 'name': 'Ulli' -> 'Chris'
Beim zweiten setName() erfolgt kein Event, da es nur dann ausgelöst wird, wenn der Wert
wirklich nach der equals()-Methode anders ist.
interface java.beans.PropertyChangeListener
extends java.util.EventListener
왘
void propertyChange( PropertyChangeEvent evt )
Wird aufgerufen, wenn sich die gebundene Eigenschaft ändert. Über das PropertyChangeEvent erfahren wir die Quelle und den Inhalt der Eigenschaft.
class java.beans.PropertyChangeEvent
extends java.util.EventObject
왘
PropertyChangeEvent( Object source, String propertyName,
Object oldValue, Object newValue )
Erzeugt ein neues Objekt mit der Quelle, die das Ereignis auslöst, einem Namen, dem alten
und dem gewünschten Wert. Die Werte werden intern in privaten Variablen gehalten und
lassen sich später nicht mehr ändern.
왘
String getPropertyName()
Liefert den Namen der Eigenschaft.
왘
Object getNewValue()
Liefert den neuen Wert.
왘
Object getOldValue()
Liefert den alten Wert.
7.3.5
Veto-Eigenschaften – dagegen!
Bei gebundenen Eigenschaften informieren Komponenten andere Komponenten, wenn sich
ein Zustand ändert. Möglicherweise haben diese Komponenten jedoch etwas dagegen. In die-
459
7.3
7
Angewandte Objektorientierung
sem Fall kann ein Zuhörer ein Veto mit einer PropertyVetoException einlegen und so eine
Werteänderung verhindern. (Es geht nicht darum, dass die Komponente selbst den Wert
ablehnt – es geht um die Interessenten, die das nicht wollen!)
Bevor wir die Änderung durchführen, holen wir also die Zustimmung dafür ein. Eine VetoEigenschaft ist insofern mit der gebundenen Eigenschaft verwandt, nur dass diese nicht in der
Lage ist zu meckern. Programmieren wir eine setXXX()-Methode mit Veto, gibt es im Rumpf
vor dem meldenden firePropertyChange() ein fragendes fireVetoableChange(), was die
Veto-Listener informiert. Der Veto-Listener kann durch eine ausgelöste PropertyVetoException anzeigen, dass er gegen die Änderung war. Das bricht den Setter ab, und es kommt nicht
zum firePropertyChange(). Wegen der PropertyVetoException muss auch die Methode
eine Signatur mit throws PropertyVetoException besitzen.
In unserem Beispiel darf die Person ein Bigamist sein. Aber natürlich nur dann, wenn es kein
Veto gab!
Listing 7.18
com/tutego/insel/bean/veto/Person.java
package com.tutego.insel.bean.veto;
import java.beans.*;
public class Person
{
private boolean bigamist;
private PropertyChangeSupport changes = new PropertyChangeSupport( this );
private VetoableChangeSupport vetos = new VetoableChangeSupport( this );
public void setBigamist( boolean bigamist ) throws PropertyVetoException
{
boolean oldValue = this.bigamist;
vetos.fireVetoableChange( "bigamist", oldValue, bigamist );
this.bigamist = bigamist;
changes.firePropertyChange( "bigamist", oldValue, bigamist );
}
public boolean isBigamist()
{
return bigamist;
}
public void addPropertyChangeListener( PropertyChangeListener l )
{
changes.addPropertyChangeListener( l );
}
public void removePropertyChangeListener( PropertyChangeListener l )
{
460
JavaBean
changes.removePropertyChangeListener( l );
}
public void addVetoableChangeListener( VetoableChangeListener l )
{
vetos.addVetoableChangeListener( l );
}
public void removeVetoableChangeListener( VetoableChangeListener l )
{
vetos.removeVetoableChangeListener( l );
}
}
Wie wir an dem Beispiel sehen, ist zusätzlich zum Veto eine gebundene Eigenschaft dabei. Das
ist die Regel, damit Interessierte auch mitbekommen, dass die Änderungen für alle gültig wurden. Denn wenn einer der Kandidaten gegen die Änderung ist, dann wird der neue Stand niemals angenommen. Die Interessenten wissen ja nichts voneinander. War jedoch keiner gegen
die Änderung, bekommen alle ein PropertyChange und wissen somit, dass alles in Ordnung
ist. Alle sind mit dem neuen Wert einverstanden.
Beginnen wir zunächst mit einer Person mit einem PropertyChangeListener, der alle gültigen Zustandswechsel meldet.
Listing 7.19
com/tutego/insel/bean/veto/PersonWatcher.java, main()
Person p = new Person();
p.addPropertyChangeListener( new PropertyChangeListener()
{
@Override public void propertyChange( PropertyChangeEvent e )
{
System.out.printf( "Property '%s': '%s' -> '%s'%n",
e.getPropertyName(), e.getOldValue(), e.getNewValue() );
}
} );
Ohne ein Veto gehen alle Zustandsänderungen durch.
try
{
p.setBigamist( true );
p.setBigamist( false );
}
catch ( PropertyVetoException e )
{
e.printStackTrace();
}
Die Ausgabe wird sein:
Property 'bigamist': 'false' -> 'true'
Property 'bigamist': 'true' -> 'false'
461
7.3
7
Angewandte Objektorientierung
Nach der Heirat darf unsere Person kein Bigamist mehr sein. Während am Anfang ein Wechsel der Zustände leicht möglich war, ist nach dem Hinzufügen eines Veto-einlegenden VetoableChangeListener eine Änderung nicht mehr erlaubt.
p.addVetoableChangeListener( new VetoableChangeListener()
{
@Override
public void vetoableChange( PropertyChangeEvent e )
throws PropertyVetoException
{
if ( "bigamist".equals( e.getPropertyName() ) )
if ( (Boolean) e.getNewValue() == true )
throw new PropertyVetoException( "Nicht mit mir!", e );
}
} );
Kern der Logik ist Anweisung throw new PropertyVetoException. Jetzt sind keine unerwünschten Änderungen mehr möglich.
try
{
p.setBigamist( true );
}
catch ( PropertyVetoException e )
{
e.printStackTrace();
}
Das setBigamist(true); führt zu einer PropertyVetoException. Der Stack-Trace ist:
java.beans.PropertyVetoException: Nicht mit mir!
at com.tutego.insel.bean.veto.PersonWatcher$2.vetoableChange(PersonWatcher.ð
java:40)
at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.ð
java:335)
at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.ð
java:252)
at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.ð
java:294)
at com.tutego.insel.bean.veto.Person.setBigamist(Person.java:19)
at com.tutego.insel.bean.veto.PersonWatcher.main(PersonWatcher.java:46)
Keine transaktionale Sicherheit
Gibt es mehrere Listener, die kein Veto einlegen und aus dem Veto-Event das Ergebnis herausnehmen, hat dies den Nachteil, dass ein Listener, der sein Veto einlegt, alles abbricht und die
alten Ergebnisse ungültig macht. Glücklicherweise entschuldigt sich dann VetoableChangeSupport, indem für die schon abgearbeiteten Listener noch einmal ein Veto mit dem alten Wert
geschickt wird. Implementieren wir die Behandlung selbst, so müssen wir den Zustand selbst
wiederherstellen und die Hörer informieren. Jetzt dürfen keine Vetos mehr auftauchen. Wenn
462
JavaBean
doch, sollten sie ignoriert werden. Das entspricht einem einfachen Undo. Damit diese Entschuldigung nicht erst beachtet werden muss, reicht es aus, auf die Auslösung von PropertyChange
zu warten, um dann sicher zu sein, dass alle das Ergebnis akzeptiert haben. Wenn wir auf ein
Veto hören, hat das den Vorteil, dass wir sukzessive den Prozess verfolgen können. Wir können
so immer wieder Vorschläge einreichen und sehen, ob sie akzeptiert werden.
Obwohl der Wunsch für eine Veto-Änderung auch einen PropertyChange darstellt, ist es fehleranfällig, für Veto- und auch gebundene Eigenschaften gleichzeitig PropertyChangeEventObjekte einzusetzen. Während bei Veto-Objekten vor der Zustandsänderung ein PropertyChangeEvent erzeugt wird, informieren die gebundenen Eigenschaften nach der Änderung
ihre Zuhörer mit einem PropertyChangeEvent. Daher bedeutet das Aufkommen eines PropertyChangeEvent jeweils etwas Unterschiedliches.
463
7.3
Vorsicht ist die Einstellung,
die das Leben sicherer macht,
aber selten glücklich.
– Samuel Johnson
25
Sicherheitskonzepte
25.1
Zentrale Elemente der Java-Sicherheit
Damit Java-Programme sicher arbeiten, greifen eine Reihe von Elementen ineinander. Einige
Dinge gibt schon die Sprache selbst vor, wie fehlende Pointerarithmetik, Sichtbarkeitsbereiche, Überwachung der Feldgrenzen, und andere ergeben sich durch die Laufzeitumgebung
selbst. Zunächst ist da der Bytecode Verifier, der grob sicherstellt, dass der Java-Bytecode korrekt geformt ist. Zu den Prüfungen zählen zum Beispiel, dass Bytecode nicht in der Mitte
enden darf, dass der Index auf Variablen korrekt ist und dass Sprünge nicht außerhalb des
Programmcodes erfolgen. Der Klassenlader ist die nächste Einheit, und sein Einfluss auf die
Sicherheit ist nicht offensichtlich. Er stellt jedoch sicher, dass sich Klassen in Paketen nicht
überschreiben können und ein selbst geschriebenes java.lang.Object nicht plötzlich das
Original überdeckt; beide befinden sich in unterschiedlichen Runtime Packages. Durch eine
Hierarchie der Klassenlader kommt eine Anforderung an die Klasse java.lang.Object auch
zuerst an den obersten Vater-Klassenlader, den Bootstrap Class Loader. Sind die Klassen geladen, überwacht zur Laufzeit der Sicherheitsmanager gültige Aufrufe; er sitzt immer zwischen
unserer Java-Applikation und dem Betriebssystem. Der Sicherheitsmanager existiert seit Java
1.0, gibt aber die Arbeit seit Java 1.2 an eine verallgemeinerte Einheit, den Access Controller,
weiter. Er nutzt Tricks wie Stack-Überprüfung, um herauszufinden, ob Aufrufer einer
Methode schon gewisse Rechte erworben haben, um die Operation ausführen zu können. Der
Access Controller stellt sicher, dass Programmcode nur dann ausgeführt werden kann, wenn
die passenden Rechte vorhanden sind.
25.1.1 Security-API der Java SE
Die Gesamtheit aller Bibliotheken, die sich in Java um die Sicherheit kümmern, wird SecurityAPI genannt. Sie trennt sich in unterschiedliche Teile auf:
왘
Verschlüsselung und Nachrichten-Authentifizierung. Seit Java 1.1 gibt es die Java-Cryptography-API. Die Java Cryptography Architecture (JCA) beschreibt, wie diese API
benutzt werden kann. Ihr ist das Paket java.security gewidmet. In Java 1.4 ist dann die
Java Cryptography Extension (JCE) hinzugekommen, die vorher nur als optionales Paket
seit 1.2 erhältlich war. Sie erweitert die Möglichkeiten der JCA. Die Klassen und Schnittstellen sind an dem Paket javax.crypto zu erkennen.
1401
25
Sicherheitskonzepte
왘
Authentifizierung und Zugriffskontrolle. Sun definiert mit dem Java Authentication and
Authorization Service (JAAS) – ein API – eine Benutzerauthentifizierung etwa über ein Kerberos-System.
왘
Public-Key-Infrastruktur. Verwalten von Schlüsseln in Key-Stores und Prüfen von digitalen X.509-Zertifikaten.
25.1.2 Cryptographic Service Providers
Die Security-API ist so entworfen worden, dass über so genannte Cryptographic Service Provider Implementierungen ausgewechselt werden können. Die Security-API von Java ist völlig
unabhängig von der Implementierung der kryptografischen Algorithmen und bietet zunächst
Schnittstellen an. Die konkreten Algorithmen wie RSA oder DES realisieren Provider – Sun ist
einer von ihnen und bringt einen Standard-Provider für grundlegende Operationen mit.
Beispiel
Welche Provider Java 6 bietet, zeigt kurz:
for ( Provider p : Security.getProviders() )
System.out.println( p + ": " + p.getInfo() );
Das Ergebnis sind neun Einträge:
SUN version 1.6, SUN (DSA key/parameter generation; DSA signing; SHA-1, MD5
digests; SecureRandom; X.509 certificates; JKS keystore; PKIX CertPathValidator;
PKIX CertPathBuilder; LDAP, Collection CertStores, JavaPolicy Policy;
JavaLoginConfig Configuration)
SunRsaSign version 1.5, Sun RSA signature provider
SunJSSE version 1.6, Sun JSSE provider(PKCS12, SunX509 key/trust factories,
SSLv3, TLSv1)
SunJCE version 1.6, SunJCE Provider (implements RSA, DES, Triple DES, AES,
Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
SunJGSS version 1.0, Sun (Kerberos v5, SPNEGO)
SunSASL version 1.5, Sun SASL provider(implements client mechanisms for: DIGESTMD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5; server mechanisms for: DIGEST-MD5,
GSSAPI, CRAM-MD5)
XMLDSig version 1.0, XMLDSig (DOM XMLSignatureFactory; DOM KeyInfoFactory)
SunPCSC version 1.6, Sun PC/SC provider
SunMSCAPI version 1.6, Sun's Microsoft Crypto API provider
Jeder Provider implementiert einen oder mehrere Algorithmen. Neue Provider lassen sich jederzeit einbringen, insbesondere dann, wenn uns die Amerikaner nicht erlauben, eine starke
Verschlüsselung zu verwenden. Eine genauere Übersicht erfährt der Leser unter http://
java.sun.com/javase/technologies/security/ und http://java.sun.com/javase/6/docs/technotes
/guides/security/crypto/CryptoSpec.html.
1402
Der Sandkasten (Sandbox)
25.2
Der Sandkasten (Sandbox)
Seit den ersten Java-Versionen gibt es das Prinzip der Sandbox, wonach Applikationen nur
ganz bestimmte Rechte haben und sich nicht mehr ergaunern können. Das gilt insbesondere
für Applets im Browser. Sie dürfen nicht das Gleiche wie Applikationen: auf Festplatten
zugreifen, die Zwischenablage auslesen und vieles mehr.
Die Sandbox besteht aus zwei Teilen, die sehr wichtig für die Java-Sicherheit sind: dem Klassenlader (Klasse ClassLoader) und dem Sicherheitsmanager (SecurityManager). Der Klassenlader lädt die .class-Dateien und erzeugt (unter anderem) die dazugehörigen Class-Exemplare. Wir wollen uns in diesem Kapitel intensiver mit dem zweiten Teil, dem Sicherheitsmanager, auseinandersetzen.
Normale Applikationen benutzen den Standardklassenlader und verwenden keinen Sicherheitsmanager. Applets aus dem Internet fordern besondere Sicherheit, sodass Browser einen
besonderen Klassenlader und Sicherheitsmanager nutzen. Der Security-Manager für Applets
erlaubt zum Beispiel kein Ausführen von externen Programmen, da auf diese Weise die Festplatte formatiert werden könnte. Auch darf ein Applet keine Klassen von einem fremden Server laden; zulässig ist nur der Server, von dem das Applet selbst geladen wurde. Diese Vorgabe stellt der Klassenlader sicher.
25.3
Sicherheitsmanager (Security Manager)
Über Applets wissen wir bereits, dass sie auf einige Ressourcen des Rechners nicht zugreifen
dürfen. Zwischen dem Aufrufer einer Bibliotheksfunktion und dem Betriebssystem sitzt eine
Einheit, die unsere Aktionen genau kontrolliert. Dieses Zwischensystem ist der Sicherheitsmanager. Standardmäßig startet die Laufzeitumgebung für Applikationen ohne Sicherheitsmana-
1403
25.2
25
Sicherheitskonzepte
ger, für Applets gibt es jedoch spezielle Sicherheitsmanager. Dies sind Exemplare von Unterklassen der abstrakten Klasse SecurityManager. Der aktuelle Sicherheitsmanager lässt sich mit
der Methode getSecurityManager() aus der Klasse java.lang.System bestimmen. Führen
wir folgende Zeile in einer Applikation aus, so sehen wir, dass anfänglich kein Sicherheitsmanager gesetzt ist, da die Ausgabe null ist.
public class ApplicationSecManager
{
static public void main( String[] args )
{
System.out.println( System.getSecurityManager() );
}
}
1404
Sicherheitsmanager (Security Manager)
Im Gegensatz dazu sind wir bei Applets mit einem etwas anderen Bild konfrontiert. Das folgende Programm liefert eine Ausgabe wie sun.applet.AppletSecurity@123456 auf dem Bildschirm. Die Zahl ist der Hashcode des Objekts:
public class Applet1 extends java.applet.Applet
{
public void paint( java.awt.Graphics g )
{
g.drawString( System.getSecurityManager().toString(), 10, 10 );
}
}
25.3.1 Der Sicherheitsmanager bei Applets
Die beiden Beispiele machen deutlich, dass dem Applet ein Security-Manager zugewiesen ist
und den Applikationen kein Sicherheitsmanager etwas verbietet. Doch was ist einem Applet
eigentlich verboten?
왘
Applets dürfen nicht auf lokale Dateien des Clientrechners zugreifen, sie etwa erzeugen,
lesen, modifizieren oder löschen. Sonst könnten sie wichtige Systemdateien an ihren Heimatserver übermitteln, und das stellt ein ernsthaftes Risiko dar.
왘
Applets können außerdem keine Netzwerkverbindungen zu anderen Computern als dem
Heimatserver aufnehmen; dies gilt für alle Verbindungen, die mit den Netzwerk-Klassen
URL, Socket und DatagramSocket möglich sind – oft einen Einschnitt darstellt, weil etwa
ein Börsenticker-Applet Kursdaten von einem anderen Server holen möchte. Das Internet
als verteiltes System sollte auch vollständig genutzt werden können. Da Applets nicht in
der Lage sind, Verbindungen zu Fremdrechnern aufzubauen, können sie natürlich auch
nicht als Server fungieren.
왘
Weiterhin kann ein Applet keine Programme ausführen, die auf dem lokalen Rechner liegen. Applets dürfen auch keine anderen Programme starten und keine nativen Bibliotheken laden. (Für normale System-DLLs bringt das ohnehin nichts, da sie nicht über die
benötigte Namenskonvention verfügen.)
왘
Threads sind ein etwas anderes Problem. Da alle Applets gemeinsam in einer JVM laufen,
muss gewährleistet sein, dass sich nur die Threads eines Applets (also die Threads in der
Thread-Gruppe des Applets) beeinflussen dürfen. In der Vergangenheit traten mehrfach
Sicherheitsprobleme auf, bei denen sich Threads verschiedener Applets in die Quere
kamen. Auch darf kein Applet die gemeinsam genutzte virtuelle Maschine beenden.
왘
Applets dürfen keinen eigenen Sicherheitsmanager installieren. Könnte das ein Applet, ließen sich leicht die für Applets geltenden Beschränkungen aushebeln. Der Java-fähige Webbrowser erzeugt für uns ein spezielles ClassLoader-Objekt, das abgesichert arbeitet.
왘
Die Java-Umgebung setzt automatisch einige Properties, damit unser Programm etwas
über seine Umgebung erfahren kann. Diese Variablen lassen sich über System.getProperty(String) auslesen. Applets dürfen nur manche Variablen lesen. Sie haben keinen
Zugriff auf Informationen über das Java-Home-Directory, den Java-Klassenpfad, den User-
1405
25.3
25
Sicherheitskonzepte
Namen, das Home-Verzeichnis und das Arbeitsverzeichnis des Anwenders. Die anderen
Daten in den Variablen sind frei. Dazu gehören etwa: java.version, java.vendor,
java.vendor.url, java.class.version, os.name, os.arch, os.version, file.separator,
path.separator, line.separator. Obwohl diese Daten natürlich für statistische Zwecke
missbraucht werden können, sind sie doch für ein Applet unter Umständen lebensnotwendig: so kann es etwa einfach an der Versionsnummer ablesen, ob eine bestimmte Klasse
mit Methoden bestimmter Versionen implementiert ist oder nicht (andernfalls muss die
Implementierung dies über eine Exception testen).
25.3.2 Sicherheitsmanager aktivieren
Nehmen wir ein Programm SecTest an, welches den aktuellen Sicherheitsmanager anzeigt
und dann die Länge einer Datei ausgibt.
Listing 25.1
com/tutego/security/SecTest.java
package com.tutego.security;
import java.io.File;
public class SecTest
{
public static void main( String[] args )
{
System.err.println( System.getSecurityManager() );
System.err.println( new File( "c:/address.txt" ).length() );
}
}
Die Schalter -Djava.security.debug und -Djava.security.manager
Wenn wir das Programm starten, läuft es durch und gibt die Länge der Datei aus. Mit dem
Schalter -Djava.security.debug=all können Sicherheitsprüfungen geloggt werden, und wir
bekommen Ausgaben wie
$ java -Djava.security.debug=all com.tutego.security.SecTest
scl: getPermissions ProtectionDomain (file:/S:/25_Sicherheitskonzepte/
<no signer certificates>)
sun.misc.Launcher$AppClassLoader@11b86e7
<no principals>
java.security.Permissions@1a46e30 (
(java.io.FilePermission \S:\25_Sicherheitskonzepte\- read)
(java.lang.RuntimePermission exitVM)
)
scl:
null
42924
1406
Sicherheitsmanager (Security Manager)
Geben wir beim Start den Schalter -Djava.security.manager an, so meldet die Laufzeitumgebung einen Standard-Sicherheitsmanager an. Ein println(System.getSecurityManager())
liefert dann eine Ausgabe wie »java.lang.SecurityManager@26b249« (auch mit -Djava.security.manager=MeineSecManagerKlasse lässt sich arbeiten).
Soll eine potenziell kritische Operation wie das Erfragen der Dateilänge ausgeführt werden,
steigt die Laufzeitumgebung mit einer Exception aus, weil der Sicherheitsmanager das standardmäßig nicht zulässt:
$ java -Djava.security.manager com.tutego.security.SecTest
java.lang.SecurityManager@26b249
Exception in thread "main" java.security.AccessControlException: access denied (
java.io.FilePermission c:\address.txt read)
at java.security.AccessControlContext.checkPermission(AccessControlContext
.java:270)
at java.security.AccessController.checkPermission(AccessController.java:401)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:542)
at java.lang.SecurityManager.checkRead(SecurityManager.java:887)
at java.io.File.length(File.java:790)
at SecTest.main(SecTest.java:9)
25.3.3 Wie nutzen die Java-Bibliotheken den Sicherheitsmanager?
Ein Sicherheitsmanager hat die Kontrolle über alle problematischen (also potenziell gefährlichen) Methoden in der Java-Bibliothek. Alle Methoden, die irgendetwas mit Sicherheit zu
schaffen haben, fragen vorher den Sicherheitsmanager, ob sie überhaupt zu der kritischen
Aktion berechtigt sind. Sehen wir uns dazu die Methode list() aus der Klasse java.io.File
an:
public String[] list()
{
SecurityManager security = System.getSecurityManager();
if ( security != null )
security.checkRead( path );
return fs.list( this );
}
Wir erkennen, dass die Methode zunächst den Sicherheitsmanager konsultiert und dann erst
die wahre Aktion ausführt. Betrachten wir das Beispiel, so ist dies typisch für alle anderen
Methoden aus der File-Klasse und macht deutlich, dass es keine Möglichkeit gibt, um diesen
Sicherheitsmanager herumzukommen; es sei denn, die Methode list() vom internen FileSystem-Objekt ließe sich direkt aufrufen – was aber nicht möglich ist, weil fs fest als privates
statisches Attribut in der Klasse File verankert ist. Sogar Unterklassen können fs also weder
sehen noch nutzen.
So wie die File-Klasse mit dem SecurityManager arbeitet, rufen auch andere Klassen Prüfmethoden auf, um zu entscheiden, ob der Zugriff auf eine Ressource erlaubt ist. Verweigert der
1407
25.3
25
Sicherheitskonzepte
Sicherheitsmanager eine Operation, löst er eine SecurityException aus. Der Sicherheitsmanager kann zum Beispiel beschränken:
왘
Toolkit. Können wir mit getSystemEventQueue() die Systemschlange für Ereignisse
abfragen?
왘
Window. Erzeugt in einem Applet zusätzlich die Einblendung »Warning: Applet Window«.
왘
FileInputStream. Dürfen wir ein solches Objekt überhaupt erzeugen?
왘
Class. Dürfen wir auf Elemente der Klasse zugreifen?
왘
ClassLoader. Können wir einen neuen Klassenlader definieren?
왘
Runtime. Können wir mit exit() aussteigen oder externe Programme ausführen?
25.3.4 Rechte durch Policy-Dateien vergeben
Um einem Programm die passenden Rechte zu geben – und damit in unserem Fall Zugriff auf
die Dateilänge zu bekommen –, werden die zugesicherten Rechte in einer Policy-Datei gesammelt. Bekommt die Laufzeitumgebung beim Start einen Verweis auf die Policy-Datei, wird der
Security-Manager auf die vergebenen Berechtigungen Rücksicht nehmen. Bei der Vergabe von
Rechten können zusätzlich angegeben werden:
왘
Codebase. Vergibt Rechte für Klassen, die von einem bestimmten Ort kommen.
왘
Signierung. Es wird nur das Recht eingeräumt, wenn Programmcode signiert ist.
왘
Principal. Bestimmte Rechte für authentifizierte Benutzer.
Policy-Dateien mit grant-Anweisungen
Die Policy-Dateien bestehen aus einer Reihe von grant-Anweisungen. Sehen wir uns die Datei
myPol.policy an, die für alle Dateien eine Leseberechtigung vergibt:
Listing 25.2
myPol.policy
grant {
permission java.io.FilePermission
};
"<<ALL FILES>>",
"read";
java.security.manager
Nun muss diese Berechtigungsdatei mit dem Sicherheitsmanager verbunden werden. Das
geschieht am komfortabelsten von der Kommandozeile aus:
$ java -Djava.security.manager -Djava.security.policy=myPol.policy
com.tutego.security.SecTest
java.lang.SecurityManager@26b249
28
Wir sehen, dass das Programm nun durchläuft und die Dateilänge ausgibt. Der Schalter -Djava.
security.policy gibt einen Pfad auf die Berechtigungsdatei an. Die Datei muss im Pfad gefunden
oder absolut adressiert werden.
1408
Sicherheitsmanager (Security Manager)
Standard-Policy-Dateien
Neben diesen benutzerdefinierten Rechte-Regeln gibt es vom System vergebene PolicyDateien. Sie werden von Java standardmäßig in der Datei java.policy im Unterverzeichnis lib/
security (etwa C:\Programme\Java\jre1.6.0\lib\security, aber auch jdk) der Java-Installation
gespeichert. Diese Rechtedatei definiert damit die »Standardberechtigungen«.
Listing 25.3
jre1.6.0\lib\security\java.policy, Ausschnitt
// Standard extensions get all permissions by default
grant codeBase "file:${java.home}/lib/ext/*" {
permission java.security.AllPermission;
};
Alle Bibliotheken, die in das ext-Verzeichnis gelegt werden, bekommen alle Rechte. Das liegt
an den Systemrechten. Das zeigt auch die Verwendung einer CodeBase: Sie spezifiziert den
genauen Pfad, in dem die Rechte gelten. Also werden nur für das lib/ext-Verzeichnis alle
Rechte vergeben, aber nicht für alle anderen.
Eigene, systemunabhängige Rechtedateien können wir unter dem Namen java.policy im
Benutzerverzeichnis ablegen. Auch diese Dateien kann der Systemverwalter anpassen.
Zunächst werden die Standardsicherheitsdateien genutzt und die Benutzerdateien »nachgeladen«. Eine weitere Datei java.security im Verzeichnis security der JRE und des JDK
beschreibt, welche Rechtedateien genutzt werden. Genau dort befinden sich die beiden
Dateien.
Listing 25.4
jre1.6.0\lib\security\java.security, Ausschnitt
# The default is to have a single system-wide policy file,
# and a policy file in the user’s home directory.
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
Die Datei ist ebenso wichtig, wenn neue Provider, also Implementierungen der KryptografieAPI, angemeldet werden.
Da Rechte nur vergeben, aber bisher nicht genommen werden können, besteht das Sicherheitsproblem darin, dass eine eigene Policy-Datei alle Rechte vergibt, wogegen die Systemdatei Einschränkungen vorsieht. In diesem Fall kann der Programmverwalter auch dem Benutzer das Recht nehmen, eigene Rechtedateien anlegen zu können. Dazu editiert er die Datei
java.security. Der Eintrag allowSystemProperty muss false sein.
# whether or not we allow an extra policy to be passed on the command line
# with -Djava.security.policy=somefile. Comment out this line to disable
# this feature.
policy.allowSystemProperty=true
1409
25.3
25
Sicherheitskonzepte
25.3.5 Erstellen von Rechtedateien mit dem grafischen Policy-Tool
Das grafische Dienstprogramm policytool gibt uns die Möglichkeit, Applikationen und signierten Applets spezielle Rechte einzuräumen oder zu verweigern. Das Policy-Tool nimmt uns die
Arbeit ab, von Hand die Rechtedateien zu editieren.
Nach dem Aufruf des Programms policytool öffnet sich ein Fenster, das uns einige Menüpunkte bereitstellt, über die wir bestehende Rechtedateien editieren oder auch neue anlegen
können.
Abbildung 25.1
Das grafische Policy-Tool
Neue Einträge für die Zugeständnisse der Laufzeitumgebung an das Programm werden über
das Menü Add Policy Entry vorgenommen. Über das Dialog-Fenster können anschließend
eine Reihe von erlaubten Eigenschaften sowie Permissions ausgewählt werden. Die folgende
Tabelle zeigt einige Permissions und ihre Bedeutungen:
Permission
Bedeutung
AllPermission
Die Anwendung oder das Applet darf alles.
FilePermission
Zugriff auf Dateien und Verzeichnisse
NetPermission
Zugriff auf Netzwerkressourcen
PropertyPermission
Zugriff auf Systemeigenschaften
ReflectPermission
Zugriff über Reflection auf andere Objekte erlauben
RuntimePermission
Einschränkungen von Laufzeitsystemen wie Klassenlader
SecurityPermission
Einstellen eines allgemeinen Sicherheitskonzepts, etwa für den Zugriff auf
Policies
SerializablePermission
Beschränkung der Serialisierung
SocketPermission
Spezielle Einschränkungen an einer Socket-Verbindung
25.3.6 Kritik an den Policies
Die Policies sind eine nette Sache, um für eine Applikation die Rechte einzuschränken oder zu
vergeben, doch sie sind nicht unproblematisch.
1410
Sicherheitsmanager (Security Manager)
Format der Policy-Dateien
Policy-Dateien sind standardmäßig Textdateien auf der Clientseite des Anwenders. Ein
Anwender kann diese Textdateien ohne große Probleme ändern und mehr Rechte zugestehen.
Die Rechtedateien sind durch keine Prüfsumme gesichert, um Änderungen gegebenenfalls zu
erkennen. Zum anderen ist das Textformat nicht mehr so »modern«, und XML-basierte Textformate lösen proprietäre Dateiformate immer mehr ab.
Da sich das Sicherheitssystem von Java jedoch beliebig erweitern lässt, lassen sich die Standardtextformate durch ein neues System ersetzen, das etwa XML-Dateien liest und eine (mit
einer digitalen Signatur gesicherte) Prüfsumme speichert, die nicht mehr so leicht veränderbar
ist.
Kein Refresh
Wurden Policy-Dateien einmal vom System eingelesen, können sie zwar nachträglich verändert werden, doch das Java-System erkennt diese Änderung nicht. Als Konsequenz muss die
Applikation neu gestartet werden. Das ist für Benutzerapplikationen kein großes Dilemma,
doch für serverseitige Applikationen ein großes Problem. Es ist unmöglich, für eine kleine
Änderung an den Policy-Dateien etwa den EJB-Server herunterzufahren und wieder neu zu
starten. Angenommen, das System ist ein Five-Nine-System, weist also eine Verfügbarkeit von
99,999 % auf, so würde dies eine erlaubte Ausfallzeit von etwa fünf Minuten ausmachen – was
bei laufender Änderung der Policies kaum zu erreichen ist.
Keine Rollen bei der Rechtevergabe
Der Zweck des Policy-Verfahrens besteht darin, einem Programm Rechte zuzuordnen. Die
Rechte können weiterhin für Programme vergeben werden, die von einem bestimmten Ort
kommen (CodeSource) und von einem bestimmten Anwender signiert sind (SignedBy). Was
wäre, wenn wir einem bestimmten Benutzer Rechte zuordnen wollten? Das ist nicht so einfach möglich. Jeder Benutzer müsste dann das Jar-Archiv signieren, und der Policy-Datei wäre
zu entnehmen, was jedem Benutzer zustünde. Doch das taugt nichts! Würde ein Benutzer hinzukommen, müsste das Archiv neu signiert werden – bei 10 000 Benutzern ein undenkbares
Unterfangen. Des Weiteren könnte der Benutzer selbst seine Rechte erweitern, was nicht
sinnvoll wäre.
Wir brauchen also nicht nur ein Verfahren, das nach den Quellen, sondern auch nach Rollen
unterscheidet. Dieses Verfahren heißt rollenbasierte Rechtevergabe. Jedem Benutzer ist eine
Rolle zugeordnet, und auf Grund dieser Rolle werden ihm Rechte zugewiesen. Das Betriebssystem Windows nutzt zum Beispiel diesen Typ der Rechtevergabe.
JAAS (Java Authentication and Authorization Service)
Sun hat die Notwendigkeit eines rollenbasierten Systems erkannt und JAAS (Java Authentication and Authorization Service) entworfen. JAAS ist Bestandteil seit Java 1.4. Die beiden
Hauptteile sind:
1411
25.3
25
Sicherheitskonzepte
왘
Authentifikation/Authentifizierung. Gibt die Identität einer Person oder eines Programms gegenüber einem Kommunikationspartner an.
왘
Autorisierung. Sicherstellen der Rechte, sodass ein Benutzer Aktionen durchführen kann
beziehungsweise ihm Aktionen verwehrt bleiben.
Das JAAS ist damit eine Java-Version eines Pluggable Authentication Module (PAM).
Wichtig in diesem Zusammenhang sind Login-Module. Sie erlauben die Anmeldung an eine
Instanz, so dass sich der Benutzer authentifizieren kann. Dies kann ein komplexes System wie
Kerberos sein, aber auch eine Smart-Card oder ein biometrisches System. Einige LoginModule liefert Sun mit jeder Laufzeitumgebung mit aus. Hat sich der Benutzer (das Subject)
mit dem Login-Modul authentifiziert, verbindet JAAS ihn mit authentifizierten Benutzerkennungen, die Principal heißen.
Bei den Policy-Dateien haben wir nun gesehen, wie die Rechte auch für eine Codebase, einem
Signierer und auch einem Principal vergeben werden können. Der Sicherheitsmanager
ermöglicht also einem Programmstück nur dann die Ausführung, wenn ein Benutzer angemeldet ist und die nötigen Rechte hat. Der Programmcode muss also keine Implementierung mit
Fallunterscheidungen für diverse Rollen aufweisen, sondern kann einfach in der Policy-Datei
mit einem Principal assoziiert werden.
25.4
Signierung
Wir wollen uns in diesem Abschnitt mit einigen Werkzeugen beschäftigen, die zur Signierung
von Applets des Java-SDK in der Standardinstallation angeboten werden. Zum Signieren von
Applikationen sowie von Applets und zur Vergabe der Zugriffsrechte und -beschränkungen
stellt Sun die Dienstprogramme keytool, jarsigner und policytool bereit.
25.4.1 Warum signieren?
Die Sandbox einer Java VM ist sinnvoll, damit Amok laufende Applikationen keine ernsthaften Schäden anrichten können. Es gibt aber genauso gut Szenarien, in denen es nützlich ist,
Applets mehr Freiräume einzuräumen. Gründe können sein: Eingebundene native Bibliotheken sollen eine Authentifizierung über das Ohrläppchen eines Anwenders vornehmen oder
auf die Festplatten zum Caching zurückgreifen können.
25.4.2 Digitale Ausweise und die Zertifizierungsstelle
Wenn nun das Java-Programm diesen Zugriff eigentlich nicht machen darf, aber möchte, was
ist die Lösung? Die Antwort ist, Programme mit einem Autor zu verbinden und die Programme dann auszuführen, wenn wir dem Autor vertrauen. Zentral bei diesem Spiel ist die
sichere Identifizierung des Autors. Das übernimmt eine Zertifizierungsstelle (Certificate
Authority, CA), die digitale Signaturen ausstellt, um eine Person oder Organisation zu identi-
1412
Signierung
fizieren. Ein Programmstück wird dann mit einer Signatur verbunden, so dass immer der
Autor bekannt ist, wenn kritische Programmstellen Unheil anrichten und ich dem Autor so
richtig meine Meinung sagen möchte.
Die Zertifizierungsstelle ist ein kleiner Schwachpunkt in diesem Szenario, denn erst einmal
hindert uns keiner daran, selbst die Zertifizierungsstelle zu spielen und das Zertifikat auf
Micky Mouse auszustellen – das machen wir auch gleich. Dem Anwender obliegt die Verantwortung, nur Zertifikate von wirklich autorisierten Stellen anzunehmen. Die Bundesnetzagentur akkreditiert Zertifizierungsstellen. Hier gibt es einige bekannte CAs wie VeriSign, CAcert
oder thawte, weitere sind unter http://www.pki-page.org/ vermerkt.
Das Zertifikat selbst verbindet die Person mit einem kryptografischen Schlüssel und weiteren
Informationen wie Seriennummer, Aussteller und Lebensdauer. Dem Schlüssel kommt die
größte Bedeutung zu, denn damit wird das Java-Archiv signiert. Der wichtigste Standard für
Zertifikate ist der ITU-T-Standard X.509. Die Zertifikate sind in ASN.1 (Abstract Syntax Notation One) kodiert.
25.4.3 Mit keytool Schlüssel erzeugen
Das Programm keytool erzeugt öffentliche und private Schlüssel und legt sie in einer passwortgeschützten und verschlüsselten Datei ab. Die Datei hat standardmäßig den Namen .keystore
und befindet sich im Benutzerverzeichnis des Anwenders. Mit dem Programm keytool lassen
sich neben der Schlüsselgenerierung auch Zertifikate importieren, Zertifikatsanforderungen
ausstellen und Schlüssel als vertrauenswürdig festlegen.
Möchten wir einen Schlüssel erstellen, rufen wir das Programm keytool mit der Option -genkey auf. Daneben gibt die Option -alias einen Namen für den Schlüsselinhaber an:
$ keytool -genkey -alias CUllenboom
Anschließend fragt keytool nach dem Passwort des Schlüsselspeichers und erfragt weitere
Angaben zum Inhaber. Mit diesen Informationen erzeugt das Programm ein Schlüsselpaar mit
einem selbstzertifizierenden Zertifikat. Bei diesem speziellen Zertifikat sind Aussteller und
Inhaber identisch.
Option
Bedeutung
-genkey
Erzeugung eines Schlüsselpaars
-import
Importieren eines Zertifikats
-selfcert
Erstellung eines selbstinitiierten Zertifikats
-certreq
Export einer Zertifikatsanforderung; sie kann als Datei an eine CA geschickt werden.
-export
Export eines Zertifikats. Dieses kann dann von einem anderen Benutzer importiert und als
vertrauenswürdig deklariert werden.
-list
Listet alle Zertifikate und Schlüssel auf.
Tabelle 25.1
Optionen von keytool
1413
25.4
25
Sicherheitskonzepte
Option
Bedeutung
-delete
Entfernt ein Schlüsselpaar.
-help
Zeigt eine kurze Hilfe an.
Tabelle 25.1
Optionen von keytool (Forts.)
Die Angabe der Optionen ist immer dann sinnvoll, wenn die Standardeinstellungen unpassend sind. Über die Optionen lassen sich die Algorithmen zur Verschlüsselung und Schlüsselgenerierung ebenso angeben wie eine Pfadangabe des Schlüsselspeichers oder die Gültigkeitsdauer.
25.4.4 Signieren mit jarsigner
Das Dienstprogramm jarsigner signiert und verifiziert Jar-Archive. Dazu erstellt jarsigner
zunächst einen Hashcode des Archivs und verschlüsselt ihn anschließend mit dem privaten
Schlüssel des Nutzers. Das Zertifikat und der öffentliche Schlüssel werden dem Archiv beigelegt.
Beispiel Signiere das Archiv archiv.jar mit dem Schlüsselspeicher (Keystore) von CUllenboom.
$ jarsigner archiv.jar CUllenboom
Die Anwendung mit jarsigner fügt dem Archiv zwei weitere Dateien hinzu: eine SignaturDatei mit der Endung .sf und eine Signaturblock-Datei mit der Endung .dsa. Die SignaturDatei enthält eine Liste aller Dateien im Archiv und speichert zudem den Hash-Wert zu einer
mit aufgeführten Hash-Funktion. Diese Signatur-Datei wird dann mit dem privaten Schlüssel
des Signierers signiert und zusammen mit dem verschlüsselten Zertifikat des Signierers in der
Signaturblock-Datei gespeichert.
Beispiel
Wir möchten wissen, ob ein Archiv verifiziert ist:
$ jarsigner -verify Archiv
25.5
Digitale Unterschriften
Ein Message-Digest, kurz MD, definiert ein Verfahren zur Erzeugung digitaler Unterschriften
für Dokumente. Der berechnende Algorithmus ist eine Einwegfunktion und liefert aus einer
Botschaft beliebiger Länge einen »Fingerabdruck« in Form einer Zahl. Die Fingerabdrücke dienen dazu, veränderte Botschaften zu bemerken. Hängen wir einer Rechnung etwa eine 0 an,
soll dies nicht unbemerkt bleiben. Wir haben ähnliche Funktionen schon beim Hash-Verfahren kennengelernt. Die meisten Klassen überschreiben die Methode hashCode() der Oberklasse Object, um einen int (also 32 Bit) als Identifizierer zu liefern.
1414
Digitale Unterschriften
Für die Begriffe »Message-Digest« und »Fingerabdruck« gibt es weitere Synonyme: Kompressionsfunktion, Kontraktionsfunktion, kryptografische Prüfsumme (falls die Unterschrift
zusätzlich verschlüsselt ist), Integritätsprüfung von Nachrichten (Message Integrity Check,
MIC) oder Erkennung von Manipulationen (Manipulation Detection Code, MDC). Ist dem
Fingerabdruck ein Schlüssel beigefügt, fällt auch der Begriff Message Authentication Code
(MAC).
25.5.1 Die MDx-Reihe
Die Firma RSA1 Data Security entwickelte mit der Reihe MD2, MD4 und MD5 drei Verfahren
zur Berechnung kryptografischer Prüfsummen. MD5 produziert 128-Bit-Hash-Werte; das ist
eine 39-stellige Dezimalzahl. Während bei MD2 (1989) und MD4 (1990) sich relativ schnell
Schwächen zeigten, dauerte es beim MD5-Verfahren (1991) mehr als 10 Jahre, bis im August
2004 von der Arbeitsgruppe um Xiaoyun Wang Methoden zur Kollision und von Patrick
Stach2 ein Kollisionsgenerator entwickelte wurde. Wir haben uns schon beim Hashing mit
Kollisionen beschäftigt. Da ein MD5-Hash-Wert 128 Bit lang ist, kann er 2^128 verschiedene
Ausgabewerte annehmen. Zwangsläufig sind unter 2^128 + 1 verschiedenen Nachrichten
mindestens zwei Texte mit gleichem Hash-Wert. Die Wahrscheinlichkeit, dass eine beliebige
Nachricht den gleichen Hash-Wert wie eine vorgegebene Nachricht hat, liegt bei 0,000 000
000 000 000 000 000 000 000 000 000 000 029 Prozent (1/2^128). (Die Wahrscheinlichkeit,
dass zwei beliebig gewählte unterschiedliche Nachrichten den gleichen Hash-Wert haben, ist
jedoch deutlich höher. Dieses Phänomen heißt Geburtstagsparadoxon.)
Die chinesische Arbeitsgruppe führte einen erfolgreichen Kollisionsangriff vor und generierte
zwei Dokumente mit dem gleichen MD5-Schlüssel. Da jedoch bisher kein Preimage-Angriff
bekannt ist, der zu einem gegebenen Dokument und einem Hash-Wert ein neues Dokument
mit gleichem Hash-Wert erzeugt, geht von dieser Möglichkeit im Moment auch keine echte
Gefahr für digitale Signaturen aus.
25.5.2 Secure Hash Algorithm (SHA)
Das National Institute of Standards and Technology (http://www.nist.gov) entwickelte im
Secure Hash Standard (SHS) den Secure Hash Algorithm (SHA)3 mit einem Hash-Wert von 160
Bit. Der Secure-Hash-Standard ist Teil des Digital-Signature-Standards (DSS), und dieser wiederum ist Teil des Capstone-Projekts. Dieses Projekt des US-Ministeriums definiert Standards
für öffentlich verfügbare Kryptografie. Es besteht aus vier Hauptkomponenten. Dazu gehören
ein symmetrischer Verschlüsselungsalgorithmus (Skipjack, auch Clipper genannt), ein Schlüsselaustauschprotokoll (bisher nicht öffentlich, ein Diffie-Hellman-Verfahren), ein Hash-Algo1 Programmiert wurde es von Ron Rivest, einem der Mitentwickler des RSA-Public-Key-Verfahrens. Daher
auch das »R«. Die Kollegen waren Adi Shamir und Leonard Adleman.
2 http://www.stachliu.com/collisions.html
3 Eine Beschreibung des Algorithmus ist unter http://www.itl.nist.gov/fipspubs/fip180-1.htm abgelegt. FIPS
ist die Abkürzung für Federal Information Processing Standards Publication – ich glaube nicht, dass es eine
Verwandtschaft mit Heinz Erhardts Fips gibt.
1415
25.5
25
Sicherheitskonzepte
rithmus (SHA) und ein Algorithmus für die digitale Unterschrift (DSA, die SHA benutzt). Die
Auswahl der Algorithmen treffen das NIST und die NSA.
Die erste Version von SHA hatte eine undokumentierte Schwachstelle, die in einer neuen
Implementierung, SHA-1, nicht mehr vorhanden ist. Wir nennen SHA-1 im Folgenden einfach
SHA und beziehen uns damit auf die neueste Version. Im Vergleich zu MD5 generiert SHA
einen Hash-Wert von 160 Bit, was Brute-force-Angriffe erschwert. Die Analysen von Xiaoyun
Wang, Yiqun Lisa Yin und Hongbo Yu zeigten jedoch auch Schwächen von SHA-1 auf. Das
Team konnte die Anzahl der Kollisionsberechnungen von Brute-Force-Angriffen von 2^80 auf
2^69 und später auf 2^63 senken – Security-Guru Bruce Schneier vermeldet auf seiner Homepage4, dass SHA-1 damit mehr oder weniger geknackt sei.
25.5.3 Mit der Security-API einen Fingerabdruck berechnen
Einstiegspunkt für Fingerabdrücke ist eine statische Methode MessageDigest.getInstance(), die ein Exemplar eines konkreten kryptografischen Algorithmus liefert. Das Argument ist ein Name für den Algorithmus, etwa »MD5« oder »SHA«. Sun implementiert in seinem JDK den DSA-Algorithmus »NIST Digital Signature Algorithm« und für digitale
Signaturen »SHA-1« und »MD5«. Da wir uns etwas näher mit Signaturen beschäftigt haben,
wollen wir zunächst die Klasse MessageDigest für digitale Fingerabdrücke untersuchen.
25.5.4 Die Klasse MessageDigest
Mit der statischen Methode getInstance() bekommen wir einen Algorithmus, der eine
bestimmte Berechnungsfunktion implementiert. getInstance() gibt es in zwei Varianten.
4 http://www.schneier.com/blog/archives/2005/08/new_cryptanalyt.html und http://www.schneier.com/blog
/archives/2005/02/sha1_broken.html
1416
Digitale Unterschriften
Beiden gemeinsam ist der Name des Algorithmus im übergebenen Argument. Die folgende
Anweisung erzeugt ein MessageDigest-Objekt für SHA:
MessageDigest digest = MessageDigest.getInstance( "SHA" );
Eine zweite Variante spezifiziert den Hersteller näher:
MessageDigest digest = MessageDigest.getInstance( "SHA", "SUN" );
Ist der Algorithmus nicht bekannt, bekommen wir eine NoSuchAlgorithmException. Ein
unbekannter Hersteller führt zu einer NoSuchProviderException.
Den Fingerabdruck berechnen
Nun können wir eine Nachricht kodieren. Dafür gibt es zwei Möglichkeiten: Die Nachricht
wird als Ganzes übergeben, oder sie wird Schritt für Schritt kodiert. Die Funktionsweise erinnert sehr an die Schnittstelle java.util.zip.Checksum.
Beispiel
Die folgenden Zeilen berechnen den Hashwert für eine Zeichenkette:
MessageDigest md = MessageDigest.getInstance( "SHA" );
md.update( "Hello".getBytes() );
Die update()-Methode ist auch für ein einzelnes Byte deklariert. Für große Dateien ist es besser, immer wieder update() auf größeren Blöcken aufzurufen, anstatt die ganze Datei auf einmal zu übergeben, da dafür die Datei vollständig im Speicher stehen müsste. Schritt für Schritt
nehmen wir mit update() immer mehr von der Nachricht hinzu.
Beispiel
Berechne den Hashwert für alle Daten eines Eingabestroms:
Listing 25.5
com/tutego/security/digest/MessageDigestDemo.java, messageDigest()
static byte[] messageDigest( InputStream in, String algo ) throws Exception
{
MessageDigest messageDigest = MessageDigest.getInstance( algo );
byte[] md = new byte[ 8192 ];
for ( int n = 0; (n = in.read( md )) > –1; )
messageDigest.update( md, 0, n );
return messageDigest.digest();
}
Den Fingerabdruck auslesen
Nach dem Sammeln berechnet die Objektmethode digest() die Signatur. Sie hat eine
bestimmte Länge in Byte, die wir mit getDigestLength() erfragen können. Da digest() ein
Byte-Array zurückliefert, ist der Wert von getDigestLength() mit der Länge des Arrays identisch. digest() lässt sich auch mit einem Bytefeld aufrufen. Ein einfaches SHA-Programm für
den String sieht daher so aus:
1417
25.5
25
Sicherheitskonzepte
Listing 25.6
com/tutego/security/digest/SHATest.java, Ausschnitt
MessageDigest md = MessageDigest.getInstance( "SHA" );
byte[] digest = md.digest( "abd".getBytes() );
for ( byte b : digest )
System.out.printf( "%02x", b );
Das Programm erzeugt die Ausgabe:
a9 99 3e 36 47 6 81 6a ba 3e 25 71 78 50 c2 6c 9c d0 d8 9d
Schon eine einfache Veränderung wirkt sich global aus. Anstatt »abc« kodieren wir jetzt »Abc«
und »abd«. Einmal ändert sich der Klein- in einen Großbuchstaben, und im anderen Fall nehmen wir einfach das nachfolgende Zeichen im Alphabet. Kein Byte bleibt gleich:
91 58 58 af a2 27 8f 25 52 7f 19 20 38 10 83 46 16 4b 47 f2
cb 4c c2 8d f0 fd be 0e cf 9d 96 62 e2 94 b1 18 9e 2a 57 35
// Abc
// abd
25.5.5 Unix-Crypt
Das unter Unix bekannte Crypt steht unter Java nicht in der Kryptografie-API zur Verfügung.
Eine quelloffene Implementierung für das Unix-Crypt findet sich zum Beispiel unter http://
tutego.com/go/javaunixcrypt.
25.6 Verschlüsseln von Daten(-strömen)
Die Kryptografie unterscheidet zwischen asymmetrischer und symmetrischer Verschlüsselung. Ist die Kommunikation asymmetrisch, sind zwei Schlüssel nötig: ein öffentlicher und ein
privater. Bei der symmetrischen Verschlüsselung ist nur ein Schlüssel nötig, der bei der Verund Entschlüsselung gleich ist. Bekanntester Vertreter der symmetrischen Verschlüsselung ist
DES (Data Encryption Standard), der allerdings wegen seiner geringen Schlüssellänge nicht
mehr aktuell ist. DES wurde 1981 in den USA als ANSI-Standard normiert. Bei den asymmetrischen Verfahren ist die RSA-Verschlüsselung die bekannteste. Ihre Sicherheit basiert auf
dem mathematischen Problem, für eine große Ganzzahl eine Primfaktorzerlegung zu finden.
Asymmetrische Verschlüsselung ist im Vergleich zu symmetrischen Verschlüsselungen langsam.
25.6.1 Den Schlüssel bitte
Jeder Schlüssel, sei er privat oder öffentlich, implementiert die Basisschnittstelle java.security.Key. Von dieser Schnittstelle gibt es Unterschnittstellen, etwa PublicKey, PrivateKey
für die asymmetrischen Schlüssel oder SecretKey für den symmetrischen Schlüssel. Von diesen Schnittstellen gibt es weitere Unterschnittstellen.
1418
Verschlüsseln von Daten(-strömen)
Schlüssel aus der Fabrik
Um Schlüssel zu erzeugen, gibt es zwei Fabriken: KeyGenerator erzeugt symmetrische Schlüssel und KeyPairGenerator asymmetrische. Der Fabrikfunktion getInstance() ist dabei eine
Kennung zu übergeben, die für den Algorithmus steht.
Listing 25.7 com/tutego/security/crypto/KeyGeneratorDemo.java, main()
KeyGenerator kg = KeyGenerator.getInstance( "DES" );
KeyPairGenerator kpg = KeyPairGenerator.getInstance( "RSA" );
Der nächste Schritt sieht eine Initialisierung des Schlüssels mit zufälligen Werten vor. Ohne
Initialisierung kann jeder Provider unterschiedlich verfahren.
kg.init( 56 );
kpg.initialize( 1024 );
// nicht größer als 56!
Schlau, wie Sun ist, wurde eine Funktion init() und die andere initialize() genannt. Toll.
Beiden Funktionen lässt sich noch ein Zufallszahlengenerator mitgeben, doch intern ist das
SecureRandom schon sehr gut. Kryptografische Angaben kann ein Objekt vom Typ AlgorithmParameterSpec einführen.
Der letzte Schritt besteht im Erfragen der Schlüssel.
SecretKey secKey = kg.generateKey();
KeyPair
keyPair = kpg.genKeyPair();
Bei einer Ausgabe des symmetrischen Schlüssels über System.out.println() kommt nicht
viel Sinnvolles heraus, doch bei den privaten und öffentlichen Schlüsseln, die keyPair mit
getPublic() und getPrivate() offenlegt, implementieren PublicKey und PrivateKey eine
ansehnliche toString()-Funktion.
System.out.println( keyPair.getPublic() );
Liefert
SunJSSE RSA public key:
public exponent:
010001
modulus:
1419
25.6
25
Sicherheitskonzepte
a8186ac3
aeb6df52
edda3a7b
004cffdd
03b9417e
0aa4d9ab
710fbf86
c103b42b
c0247c70
ae35a5d5
0274a2a6
9abf216d
d225ae75
d7b30f38
842c4d73
5f797440
04d2fa3b
ce670895
76fc2166
20b8ec52
9b21e009
3234fab2
80ef1e82
afe44407
ca32a1f3
c67f1211
36a949f9
a871e1f7
3cc7404f
b9dab8d2
8180c5c7
0e27fec9
System.out.println(keyPair.getPrivate()) liefert eine noch längere Ausgabe mit Expo-
nent, Modulo usw.
SecretKeySpec
Schlüssel für die symmetrische Verschlüsselung sind nichts anderes als Binärfelder. Die Klasse
javax.crypto.spec.SecretKeySpec dient zum Erzeugen eines symmetrischen Schlüssels und
erwartet im Konstruktor das Bytefeld und den Algorithmus.
Key k = new SecretKeySpec( "01234567".getBytes(), "DES" );
Für andere Typen existieren wiederum andere Klassen. Zum Beispiel erzeugt DSAPrivateKeySpec einen privaten Schlüssel aus dem privaten Schlüssel, zwei Primzahlen und einer
Basis, die als BigInteger-Objekte angegeben sind.
25.6.2 Verschlüsseln mit Cipher
Die Klasse javax.crypto.Cipher bildet das Zentrum der JCE. Nachdem init() das Objekt
mit einem Modus und Schlüssel initialisiert hat, lassen sich mit update(byte[]) Daten durchschleusen. doFinal() rundet das Ganze dann ab. Die Rückgabe ist immer ein verschlüsselter
Block von byte.
Cipher cipher = Cipher.getInstance( "DES" );
cipher.init( Cipher.ENCRYPT_MODE, key );
byte[] verschlüsselt = cipher.doFinal( unverschlüsselt );
Beim Entschlüsseln wird der Cipher einfach in den Modus Cipher.DECRYPT_MODE gesetzt.
25.6.3 Verschlüsseln von Datenströmen
Zum Verschlüsseln von Datenströmen bietet das Java-SDK die praktischen Klassen
javax.crypto.CipherInputStream und CipherOutputStream an. Sie erwarten ein CipherObjekt, das eine DES-Verschlüsselung durchführt.
Listing 25.8
com/tutego/security/crypto/ReadWriteDES.java
package com.tutego.security.crypto;
import
import
import
import
import
1420
java.io.*;
java.security.Key;
javax.crypto.*;
javax.crypto.spec.SecretKeySpec;
sun.misc.*;
Verschlüsseln von Daten(-strömen)
public class ReadWriteDES
{
static void encode( byte[] bytes, OutputStream out, String pass ) throws Exception
{
Cipher c = Cipher.getInstance( "DES" );
Key k = new SecretKeySpec( pass.getBytes(), "DES" );
c.init( Cipher.ENCRYPT_MODE, k );
OutputStream cos = new CipherOutputStream( out, c );
cos.write( bytes );
cos.close();
}
static byte[] decode( InputStream is, String pass ) throws Exception
{
Cipher c = Cipher.getInstance( "DES" );
Key k = new SecretKeySpec( pass.getBytes(), "DES" );
c.init( Cipher.DECRYPT_MODE, k );
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CipherInputStream cis = new CipherInputStream( is, c );
for ( int b; (b = cis.read()) != –1; )
bos.write( b );
cis.close();
return bos.toByteArray();
}
public static void main( String[] args ) throws Exception
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
encode( "Das wird anders werden".getBytes(), out, "01234567" );
String s = new BASE64Encoder().encode( out.toByteArray() );
System.out.println( s ); // qJYN+8Hd5dXsgMl1akQnw4iCbRN3EUbK
byte[] decode = new BASE64Decoder().decodeBuffer( s );
InputStream is = new ByteArrayInputStream( decode );
System.out.println( new String( decode( is, "01234567" ) ) );
}
}
1421
25.6
25
Sicherheitskonzepte
25.7
Zum Weiterlesen
Da unter Sicherheit jeder etwas anderes versteht, sind auch die Möglichkeiten zum Weiterlesen nahezu unbeschränkt. Die Verifizierung ist sehr trickreich, und insbesondere ein finallyBlock verlangt einiges an Aufmerksamkeit. Das Kapitel 4.9 der »Java Language Specification«
beschreibt die Validierung genauer. Auf die Probleme geht der Artikel »The Problem of Bytecode Verification in Current Implementations of the JVM« (http://citeseer.ist.psu.edu/
484520.html) etwas genauer ein. Das Zusammengreifen der einzelnen Elemente wie Klassenlader, Verifier, Sicherheitsmanager ist gut im Online-Kapitel von »Inside the Java Virtual Machine« (http://www.artima.com/insidejvm/ed2/security.html) nachzulesen.
1422
Index
#ifdef 61
#IMPLIED 849
#REQUIRED 848
$, innere Klasse 409, 414
%% 281
%, Modulo-Operator 113
%, Operator 303
%b 281
%c 281
%d 281
%e 281
%f 281
%n 281
%s 281
%t 281
%tD 647
%tR 647
%tT 647
%x 281
&&, logischer Operator 119
&, Generics 424
&amp 846
&apos 846
&gt 846
&lt 846
&quot 846
*, Multiplikations-Operator 112
*7 56
+, Additions-Operator 112
-, Subtraktions-Operator 112
..., Variable Argumentlisten 217
.class 498, 1341
.java.policy 1409
.keystore 1413
.NET Remoting 1207
/, Divisions-Operator 112
//, Zeilenkommentar 93
<exec>, Ant 1428
=, Zuweisungsoperator 111
== 193
?, Generics 425
@{code, JavaDoc} 432
@author, JavaDoc 432
@category, JavaDoc 432
@Deprecated 438, 540
@deprecated 540, 1339
@deprecated, JavaDoc 437
@Documented 1380
@exception, JavaDoc 432
@javax.management.MXBean
1394
@link, JavaDoc 432
@linkplain, JavaDoc 432
@literal, JavaDoc 432
@OneWay 1224
@Override 378, 397, 540, 1373
@param, JavaDoc 432
@Retention 1380
@return, JavaDoc 432
@see, JavaDoc 432
@SOAPBinding 1224
@SuppressWarnings 540, 657,
1373
@Target 1379
@throws, JavaDoc 432
@version, JavaDoc 432
@WebMethod 1224
@WebParam 1224
@WebResult 1224
@WebService 1224
@XmlElement 891
@XmlRootElement 891
[L 1346
^, logischer Operator 119
||, logischer Operator 119
100% Java-Kompatibel 75
1099, Port rmiregistry 1215
200, OK 1184
404, Not Found 1184
500, Internal Server Error 1184
80, Http-Port 1180
8080, Http-Port 1180
A
abrunden 300
abs(), Math 298
Absolutwert 173
Abstract Syntax Notation One
1413
Abstract Window Toolkit 895
abstract, Schlüsselwort 391–392
AbstractAction, Klasse 930
AbstractBorder, Klasse 932
AbstractButton, Klasse 927
AbstractTableModel, Klasse 1015
abstrakte Klasse 391
abstrakte Methode 392
Absturz der Ariane 5 126
Accelerator 981
accept(), ServerSocket 1173
Accepted 1184
Access Controller 1401
Accessibility 897
Accessible, Schnittstelle 1059
AccessibleObject, Klasse 1353,
1368
Action, Schnittstelle 930, 980
ACTION_PERFORMED, ActionEvent 913
Action-Command 929
ActionListener, Schnittstelle 916,
923, 925
Activatable, Klasse 1221
Activation Daemon 1222
activation.jar 1196
Adapter 681
Adapter, MBean 1388
Adapterklasse 920
add(), Container 906, 940
addActionListener(), JButton 925
addItem(), JComboBox 994
Addition 112
addKeyListener(), Component
936
addWindowListener() 919
Adjazenzmatrize 215
Adjustable, Schnittstelle 965
AdjustmentEvent, Klasse 964
AdjustmentListener, Schnittstelle 967
Adleman, Leonard M. 1415
Adler32, Klasse 819
affine Transformation 1134
AffineTransform, Klasse 1135
Age, Response-Header 1185
Aggregationsfunktionen 1336
Ahead-Of-Time Compiler 1436
AIFF 538
Aktor 181
aktueller Parameter 152
1457
Index
Al Gore 1143
AlgorithmParameterSpec, Schnittstelle 1419
Algorithmus 655
-alias 1413
allgemeine Semaphor 603
Allow, Entity Header 1185
allowSystemProperty 1409
AllPermission 1410
AlphaComposite, Klasse 1104
AlreadyBoundException 1216
AM_PM, Calendar 642
Amigos 180
Anführungszeichen 109
angehäufte if-Anweisungen 133
angepasster Exponent 292
Anhängen an Strings 244
Anhängen von Zeichen 253
Animierter Cursor 1128
Anmelde-/Versendesystem 1227
AnnotatedElement, Schnittstelle
1361, 1381
Annotation, Schnittstelle 1382
Annotationen 539
annotiert 1339
anonyme innere Klasse 413
Anpassung 455
Ant 1428, 1446
Antialiasing 1075, 1134
Anweisung 92
Anweisungssequenz 99
Anwendungsfall 181
ANY 848
Anzahl Einträge 1337
Apache Axis 1223
Apache Commons CLI 228
Apache Commons Codec 280
Apache Commons Collections
715
Apache Commons Compress 806
Apache Commons DBCP 1310
Apache Commons IO 743, 762
Apache Commons Logging 1399
Apache Commons/Net 1178–
1179
Apache Jakarta HttpClient 1178
append(), StringBuffer/StringBuilder 254
Appendable, Schnittstelle 254,
772
Apple, Look-And-Feel 1045
1458
Applet 56, 65, 1267
AppletContext 538, 1271, 1276
appletviewer 1435
Applikations-Klassenlader 515
APRIL, Calendar 638
Ära 651
Arc2D, Klasse 1089–1090
Arcus-Funktionen 299
Area, Klasse 1091
AreaAveragingScaleFilter, Klasse
1122
Argument der Funktion 152
ArithmeticException 308, 480
arithmetische Typen 100
arithmetischer Operatorer 112
Array 204
Array, Klasse 1350
arraycopy(), System 219
Array-Grenze 61
ArrayIndexOutOfBoundsExceptions 480
ArrayList 662
ArrayList, Klasse 361, 656, 661,
669, 677
ArrayStoreException 381, 683
Array-Typen 100
Artefakte 1125
Aschermittwoch 640
ASCII-Zeichen 85
asin(), Math 299
asList(), Arrays 226, 681, 690
ASN.1 1413
assert, Schlüsselwort 489
Assertion 489
AssertionError 489
assignment 111
Assistive technology 1059
Assoziation 359
assoziativer Speicher 662
Astronomie 623
Atlantic City 64
atomar 574
atomare Komponente 906
Atomuhr 624
Attribute 179, 844
Attributinhalte 882
AU 538
AudioClip, Klasse 537
aufgeschobene Initialisierung
161
Aufruf einer Funktion 150
Aufrunden 300
AUGUST, Calendar 638
Ausdruck 111
Ausdrucksanweisung 96–97
Ausführungsstrang 543
Ausgabeformatierung 624
Ausnahme 61
Ausnahmenbehandlung 61
Ausprägung 179
Ausprägungsvariable 183
ausschließendes Oder 119
äußere Schleife 143
Auswahlmenü 992
Auszeichnungssprachen 843
authentication required 1151
Authenticator, Klasse 1157
Authentifizierung 1412
Autoboxing 200
Auto-Commit 1328
Automatische Typanpassung 122,
371
Autorisierung 1412
await(), Condition 593
AWT 895
AWTEvent, Klasse 913
AWTEventListener, Schnittstelle
1059
AWT-Event-Thread 919, 1053
AWT-Input 566
AWT-Motif 566
B
Bad Gateway 1184
Bad Request 1184
barrier 562
Base64 280
Base64 Encoding 1196
baseline 1080
Basic Multilingual Plane 86
BasicStroke, Klasse 1105
BatchUpdateException 1320
Beautifier 1452
bedingte Compilierung 61
Bedingungsoperator 121, 172
Behinderungen, Accessibility 897
Beispielprogramme der Insel 49
Benutzerdefinierter Klassenlader
515
Benutzerinteraktion 1060
Beobachter-Pattern 448
Index
Berkeley-Socket Interface 1166
Betrag 298
BevelBorder, Klasse 932
Bezeichner 88
Bézier-Kurve 1091
Bias 292
biased exponent 292
bidirektionale Beziehung 359
BigDecimal, Klasse 308, 313
Big-Endian 309
BigInteger, Klasse 308
Bilder skalieren 1121
Bildlaufleiste 962
Bildschirmabzug 1063
binäre Semaphor 603
binäre Suche (binary search) 722
binärer Operator 110
Binary and Floating-Point
Arithmetic 292
binarySearch(), Arrays 225, 687
bind(), Registry 1215
Binnenmajuskel 89
bin-Pfad 72
biometrisches System 1412
Birrel 1205
Bitmenge 727
BitSet, Klasse 727
Bitttage 640
bitweise Manipulation 727
bitweises Exklusives Oder 167
bitweises Komplement 120
bitweises Oder 121, 167
bitweises Und 121, 167
bitweises Xor 121
Block 99
BlockingQueue, Schnittstelle 701
Block-Tag 434
boolean, Datentyp 101
Boolean, Klasse 202
Bootstrap-Klassenlader 515
Border, Schnittstelle 932
BorderFactory, Klasse 934
BorderLayout, Klasse 948, 951
bound properties 457
BoundedRangeModel, Schnittstelle 964
Bound-Properties 456
Boxing 200
BoxLayout 961
BoxLayout, Klasse 947, 961
break 143–144
BreakIterator, Klasse 275
brighter(), Color 1099
Brightness 1100
Browser-Version 523
Bruch 317
Bruchzahl 291
Bucket, Hash-Table 713
BufferedImage, Klasse 1118
BufferedInputStream, Klasse 763,
789
BufferedOutputStream 787
BufferedReader, Klasse 763, 789
BufferedWriter 787
build.xml 1446
ButtonGroup, Klasse 973
Byte 166
byte, Datentyp 101, 106, 291
Byte, Klasse 197
ByteArrayInputStream, Klasse
786
ByteArrayOutputStream, Klasse
785
Bytecode 57, 95
Bytecode Verifier 1401
BZip2 806
C
C 55
C# 200
C++ 55, 178
Cache, Bilder 1127
Cache-Control 1185
CachedRowSet, Schnittstelle
1322
CachedRowSetImpl, Klasse 1322
CAG (Constructive Area
Geometry) 1091
Calendar, Klasse 624, 635
call by reference 192
call by value 152, 191
Callable, Schnittstelle 569
CallableStatement, Schnittstelle
1310
CANON_EQ, Pattern 264
Canvas 1109
CAP_BUTT, BasicStroke 1106
CAP_ROUND, BasicStroke 1106,
1108
CAP_SQUARE, BasicStroke 1106
CardLayout, Klasse 948
Caret 1006
CASE_INSENSITIVE, Pattern 264
CASE_INSENSITIVE_ORDER,
String 691
Cast 120
Cast, casten 122
catch 465
CDATA 848
CDC (Connected Device Configuration) 1282
ceil(), Math 300
Central European Time 632
CERN 1180
Certificate Authority, CA 1412
CET 632
ChangeListener, Schnittstelle 963
char, Datentyp 101, 109
Character, Klasse 233
CharArrayReader, Klasse 784
CharArrayWriter, Klasse 783
CharSequence, Schnittstelle 238,
439
Checkbox, Klasse 968
checked exception 480
checkError() 775
Checksum, Schnittstelle 817
choice box 992
Christi Himmelfahrt 640
Cipher, Klasse 1420
CipherInputStream, Klasse 1420
CipherOutputStream, Klasse
1420
class literal 498
Class Loader 512
Class, Klasse 498, 1340
class, Schlüsselwort 319, 1349
ClassCastException 480
ClassLoader, Klasse 515, 1403
ClassNotFoundException 1341–
1342
CLASSPATH 514, 1437, 1443
-classpath 514, 1437
Class-Path Wildcard 1438
Client 1167, 1207
Client/Server-Kommunikation
1172
Clip-Bereich 1070
Clipboard 982, 1046
Clipboard, Klasse 1046
Clipper 1415
clipping 1095
1459
Index
Clipping-Bereich 1130
clone() 504
clone(), Arrays 218
CloneNotSupportedException
505, 507
Closeable, Schnittstelle 766
closePath(),Path2D 1094
Cloudscape 1290
Clustering, Hash-Tabelle 713
cmd.exe 527
code point 85
Codebase 1408
CollationKey, Klasse 261
Collator, Klasse 258, 685, 691
Collection API 655
Collection, Schnittstelle 657–658
Collections, Klasse 656
Color, Klasse 1096
com.sun.image.codec.jpeg, Paket
1110
com.sun.net.httpserver, Paket
1186
com4j 1433
combo box 992
ComboBoxModel, Schnittstelle
992
Command Model 916
Command not found 71
command.com 527
Comparable, Schnittstelle 400,
685
Comparator, Schnittstelle 685
compare(), Comparator 686
compareTo(), Comparable 686
compareToIgnoreCase(), String
241
compile(), Pattern 263
Compiler 95
Component, Klasse 931
ComponentEvent, Klasse 915
ComponentListener, Schnittstelle 939
ComponentUI, Klasse 991
Composite Pattern 940
Composite, Schnittstelle 1104
CompoundBorder, Klasse 932
concat(), String 245
CONCUR_UPDATABLE, ResultSet 1318, 1323
ConcurrentHashMap, Klasse 725
1460
ConcurrentLinkedQueue, Klasse
725
ConcurrentMap, Schnittstelle
725
ConcurrentModificationException 669
ConcurrentSkipListMap, Klasse
662
ConcurrentSkipListSet, Klasse
725
Condition, Schnittstelle 593
Connected Limited Device Configuration (CDC) 1281
Connection 1185
Connection, Schnittstelle 1300
Connector/J 1291
Connector-Level 1388
Console, Klasse 781
const, Schlüsselwort 161–162
const-korrekt 162
Constraint-Properties 456
Constructor, Klasse 1359
Contact Port 1167
Container 655
contains(), Shapre 1094
contains(), String 238
containsKey(), Map 706
Content Handler 1154
Content-Base 1185
Content-Encoding 1185–1186
contentEquals(), String 256
Content-Handler 1151
ContentHandler, Schnittstelle
865
Content-Language 1185
Content-Length 1185
Content-Location 1185
Content-MD5 1185
Content-Pane 907
Content-Range 1185
Content-Type 1185
continue 143, 145
Controller 991
Copy-Konstruktor 346, 504
copyOf(), Arrays 222
copyOfRange(), Arrays 222
CopyOnWriteArrayList, Klasse
669, 727
CopyOnWriteArraySet, Klasse
727
CORBA (Common Object Request
Broker Architecture) 1207,
1220
cos(), Math 299
cosh(), Math 300
Cosinus 299
Cosmo 164
-cp 514, 1438
Cp037 278
Cp850 278
CRC32, Klasse 818
CREATE TABLE 1337
createCompatibleImage(), GraphicsConfiguration 1118
Created 1184
createGraphics(), BufferedImage
1118
createStatement(), Connection
1310
Crimson 855
Cryptographic Service Providers
1402
CSV (Comma Separated Values)
841
CubicCurve2D, Klasse 1089
currency, Datentyp 109
currentThread(), Thread 552
currentTimeMillis(), System 525
Cursor 1127
curveTo(), GeneralPath 1091
custom tag library 1244
Customization 455
CVM 1282
cxxwrap 1433
CyberNeko 894
CyclicBarrier, Klasse 562
D
-D 523
Dämon 564
dangling pointer 355
Dangling-Else Problem 131
darker(), Color 1099
dash attribute 1105
Data Hiding 327
Data Query Language 1335
Database Management Systems
1289
DatabaseMetaData, Schnittstelle
1332
Index
DataFlavor, Klasse 1048
Datagramme 1189
Datagrammsockets 1187
DatagramPacket, Klasse 1189
DatagramSocket, Klasse 1187,
1189
DataInput, Schnittstelle 754, 823
DataInputStream, Klasse 795
DataOutput, Schnittstelle 754,
823
DataOutputStream, Klasse 795
Datapoint 57
DataSource 1307
DataSource, Schnittstelle 1307
DataTruncation, Klasse 1318
DATE, Calendar 642
Date, General Header Fields 1185
Date, Klasse 624, 634
DateFormat, Klasse 284, 624,
647, 652
Dateiauswahl-Dialog 1040
Dateiauswahldialog 1040
Dateinamenendungen 242
Dateiverknüpfung 737
Datenbankausprägung 1289
Datenbankschema 1289
Datenbankverbindung 1305
Datenbasis 1289
Datenkompression 805
Datenstrukturen 655
Datentyp 100
Datenzeiger 754
Datumswerte 624
DAY_OF_MONTH 642
DAY_OF_WEEK, Calendar 642
DAY_OF_WEEK_IN_MONTH,
Calendar 642
DAY_OF_YEAR, Calendar 642
DBMS 1289
-Dcom.sun.management.jmxremote 1392
Deadlock 544, 590
DECEMBER, Calendar 638
DecimalFormat, Klasse 286
Decompiler 1450
Decrement 120
default 134
default, Schlüsselwort 1378
DEFAULT_LAYER 1033
DefaultHandler, Klasse 865–866
Default-Konstruktor 186, 343
DefaultListCellRenderer, Klasse
1002
DefaultListModel, Klasse 998,
1001
DefaultMutableTreeNode, Klasse
1028
Default-Paket 230
defaultReadObject(), ObjectInputStream 830
DefaultTableCellRenderer, Klasse
1020
DefaultTableModel, Klasse 1018
defaultWriteObject(), ObjectOutputStream 829
DEK 306
Dekonstuktor 510
Dekoration 905
delegate 74
Delegation Model 916
DELETE 1181
delete() 60
delete(), StringBuffer/StringBuilder 255
Delimiter 266, 274
Deployment-Descriptor 1234
Deprecated 436
deprecated 1436
-deprecation 437
Deque 700
Deque, Schnittstelle 661
Derby 1290
dereferenced-Meldung 1218
Dereferenzierung 128
deriveFont(), Font 1082
DES (Data Encryption Standard)
1418
Design-Pattern 447
Desktop, Klasse 529
Dezimalpunkt 292
DGC 1218
Dialog 1035–1036
Digitale Unterschriften 1414
DirectX 74
Distributed Component Object
Model (DCOM) 1207
distributed GC 1218
Dividend 112
Divider 944
Division 112
Divisionsoperator 112
Divisor 112
-Djava.rmi.dgc.leaseValue 1218
-Djava.rmi.server.codebase 1220
-Djava.security.debug 1406
-Djava.security.manager 1407
-Djava.security.policy 1408
-Djdbc.drivers 1301
dll-Dateien 1427
DnD, Drag & Drop 1050
DNS 1143, 1276
do/while-Schleife 138
Doc Comment 431
Doclet 435, 1340
DOCTYPE 849
Document Object Model 854
Document Type Definition 847
Document, Klasse 871
DocumentBuilderFactory 856
Dokumentationskommentar 431
DOM 854
DOM Level 3 XPath 885
Domain Name Service 1143
Domain Name System 1189
Domain-Name-Server 1276
DOMBuilder, Klasse 872
Donald E. Knuth 306
Doppel-Pufferung, Swing 944
DOS-Programme 527
DOTALL, Pattern 264
double 292
double, Datentyp 101
Double, Klasse 197
Double-Buffering, Swing 944
doubleToLongBits(), Double 510
DQL 1335
Drag & Drop 1050
Drag and Drop 897
draw(Shape), Graphics2D 1089
draw3DRect(), Graphics 1099
drawImage(), Graphics 1113
drawLine(), Graphics 1076
drawString(), Graphics 1080
Drehfeld 1002
DriverInfo 1306
DriverManager, Klasse 1301,
1304
Drucken 1136
DSAPrivateKeySpec, Klasse 1420
DSN 1189
DST_OFFSET, Calendar 643
DTD 847
DTDHandler, Schnittstelle 865
1461
Index
Durchschnittswerte 1336
Durchschuss 1086
-Duser.timezone 638
dynamic invocation 1369
dynamic linked libraries 1427
Dynamic MBeans 1389
Dynamische Datenstrukturen
655
Dynamischer Methodenaufruf
1371
Dynamisches Layout 905
E
-ea 490
EBCDIC 799
EBCDIC-Zeichensatz 278
Echozeichen 1006
Eclipse 73
Eclipse Translation Packs 75
EclipseME 1284
ECML 1240
Editor-Kit 1010
Eiche 55
Eigenschaft 455
einfache Eigenschaft 455
einfache Hochkommata 109
Einfachvererbung 365
eingeschränkte Eigenschaft 456
Einstelliger Operator 110
Electronic Commerce Modeling
Language 1240
Element suchen 721, 723
Element, Klasse 874
Element, XML 844
elementare Anweisung 99
Elementklasse 409
ElementType, Aufzählung 1379
Ellipse, UML 181
Ellipse2D, Klsse 1089
else 130
Elternklasse 363
Embedded Java 68
EmptyBorder, Klasse 932
EmptyStackException 480, 699
enable assertions 490
encoding 278
end caps 1106
Ende der Welt 165
Endlosschleife 137
endorsed-Verzeichnis 514, 519
1462
Endpoint, Klasse 1225
endsWith(), String 242
ENGLISH 626
ensureCapacity(), List 679
Enterprise Edition 68
entfernte Methoden 1205
entfernte Methodenaufrufe 1205
entfernte Objekte 1211
Entitäten 846
Entity 1185
Entity Header 1185
Entity-Body 1185
Entity-Header 1183, 1185
EntityResolver, Schnittstelle 865
entrySet(), Map 709
Entwurfsmuster 447
Enum, Klasse 426
enum, Schlüsselwort 339, 489
Enumeration, Schnittstelle 665
Enumerator 665
EnumMap, Klasse 444
EOFException 753
equals() 500–501, 1148
equals(), Arrays 220
equals(), Object 193, 500
equals(), Point 194
equals(), String 256
equalsIgnoreCase(), String 240
ERA, Calendar 642
Erdzeitalter 166
Ereignis, Gui 913
Ereignisauslöser 916
Ereignisschlange 1053
Ereignisse 455
Ergebnistyp 148
erreichbar, catch 475
erreichbarer Quellcode 154
Error, Klasse 476, 480
ErrorHandler, Schnittstelle 865
erweiterte for 211
Erweiterungs-Klassenlader 515
Erzeuger/Verbraucher 596
Escape-Sequenz 109
Escape-Zeichen 239
Escher, Maurits 175
ETag 1185
EtchedBorder, Klasse 932
Eulersche Zahl 297
Euro-Zeichen 87
Event Queue 1053
Event-Dispatching-Thread 919
EventFilter, Schnittstelle 861
EventListener, Schnittstelle 452
EventObject, Klasse 452
Eventquelle 916
EventQueue, Klasse 1053, 1055,
1058
Events 455
Event-Source 916
Excelsior JET 1436
Exception 61
Exception, Klasse 476
ExceptionInInitializerError 336
Exchanger, Klasse 562
exec(), Runtime 526
executeQuery(), Statement 1312
executeUpdate(), Statement 1312
Executor, Schnittstelle 566
ExecutorService, Schnittstelle
567
Exemplar 179
Exemplarinitialisierer 353
Exemplarinitialisierungsblock
416
Exemplarvariable 183, 330
exit(), System 228
EXIT_ON_CLOSE, JFrame 901
exklusives Oder 119
Expires 1185
explizite Typanpassung 122
explizite Typumwandlung 373
explizites Klassenladen 513
Explorer 65
Exponenten 292
Exponentialwert 302
exportObject(), UnicastRemoteObject 1215
expression 111
extends, Schlüsselwort 363, 403
eXtensible Markup Language 844
Extension-Verzeichnis 514
F
Fabrik 448
Fabrikmethode 358
Facelets 1266
Factory 448
Faden 543
Fakultät 312
Fall-Through 134
false 101
Index
Farbauswahl 1038
Farbe 1096
Farbmodell 1101
Farbsättigung 1100
FEBRUARY, Calendar 638
Federal Information Processing
Standards Publication 1415
Fee, die gute 162
Fehler 477
Fehlercode 465
Feld 204
Feld-Typen 100
fencepost error 141
Fenster 900
Fenstermenü 976
Field, Klasse 1352–1353, 1363
FIFO-Prinzip 661
File,Klasse 732
file.encoding 799
File.separatorChar 733
FileChannel, Klasse 747
FileDescriptor, Klasse 762
FileFilter, Klasse 1040
FileFilter, Schnittstelle 741
FileInputStream, Klasse 759
FilenameFilter, Schnittstelle 741
FileNotFoundException 466, 477
FileOutputStream, Klasse 759
FilePermission 1410
FileReader, Klasse 758
FileWriter, Klasse 756
fill(), Arrays 221
fill(), Collections 720
fillInStackTrace(), Throwable 485
FilteredRowSet, Schnittstelle
1322
FilterInputStream, Klasse 795
FilterOutputStream, Klasse 795
FilterReader, Klasse 795
FilterWriter, Klasse 795
final 160
final, Schlüsselwort 337, 389–
390, 1349
finale Klasse 389
finale Methode 390
finale Werte 352
finalize() 510
Finalizer 510
finally, Schlüsselwort 472
findClass(), ClassLoader 516
Fingerabdruck 1414
FIPS 1415
Firewall 1220
First Person, Inc. 56
First-In-First-Out 661
Fitts’s Law 949
Five-Nine System 1411
flache Kopie 712
flache Kopie, clone() 507
Flaubert, Gustave 1435
Fließkommazahl 100, 108, 291
Fließpunktzahl 291
float 292
float, Datentyp 101
Float, Klasse 197
floatToIntBits(), Float 510
floor(), Math 300
FlowLayout, Klasse 947, 949
Fluchtsymbole 109
Flushable, Schnittstelle 766
FocusEvent, Klasse 915
FocusListener, Schnittstelle 935
Fokus 935
Font, Klasse 908, 1081
FontFormatException 1084
FontMetrics, Klasse 1085
FontRenderContext, Klasse 1087
Forbidden 1184
formale Typ-Parameter 419
formaler Parameter 152
format() 775
format(), Format 285
format(), String 281
Format, Klasse 284
Formatierungsanweisungen 648
Formatierungsstrings 651
Format-Spezifizierer 281
Format-String 281
Formatter, Klasse 282
forName(), Class 1341
for-Schleife 140
Fortschaltausdruck 140
Fortschrittsbalken 974
Fragezeichenoperator 110
Frame 900
Frame, Klasse 902
FrameMaker 50
FRANCE 626
free() 60
FRENCH 626
Fronleichnam 640
FULL, DateFormat 649
Füllfaktor 713
Füllmuster 1108
Füllung, Paint 1095
Funktion 94, 150
Funktionsaufruf 95
Funktionszeiger 443
G
Ganzzahl 100
ganzzahliger Datentyp 106
Garbage-Collector 60, 182, 186,
342, 355
Gauß-Normalverteilung 308
GC 60, 342, 355
GCC 1427
gcj 1436
gebundene Eigenschaft 456–457
gebundene Property 943
Geburtsdatum 644
Geburtstagsparadoxon 1415
gegenseitiger Ausschluss 574,
577
Geltungsbereich 104
General-Header 1183
GeneralPath, Klasse 1091
Generic Connection Framework
1282
Generics 419
generischer Typ 419
-genkey 1413
geordnete Liste 661
Georg Shar 439
geprüfte Ausnahme 480
GERMAN 626
GERMANY 626
geschachtelte Alternativen 132
geschachtelte Ausnahme 485
geschachtelte Top-Level Klasse
408
GET 1181
get(), List 670
get(), Map 705
getBytes(), ResultSet 1317
getBytes(), String 278
getChars(), String 244
getColumnClass(), TableModel
1015
getColumnCount(), TableModel
1015
1463
Index
getColumnName(), TableModel
1015
getConnection(), DriverManager
1301
getContentPane(), JFrame 907
getContextClassLoader(), Thread
520
getDefaultToolkit(), Toolkit 899
getenv(), System 525
getInstance(), Calendar 638
GET-Methode 1159, 1180
getPriority(), Thread 563
getProperties(), System 521
getProperty(), Properties 715
getResource() 768
getResourceAsStream() 768
getRowCount(), TableModel
1015
getStackTrace(), Thread 487
GetStringUTFChars 1429
getTableCellEditorComponent(),
TableCellEditor 1023
Getter 329
getText(), JLabel 907
getText(), JTextComponent 1005
getTimeInMillis(), Calendar 641
getValueAt(), TableModel 1015
ggT 308
GIF 1109
Glass-Pane 1032
Gleichheit 194
Gleitkommazahl 291
globale Variable 104
Glyphe 1080
GMST 623
Goldsäule 165
Gosling, James 55
goto, Schlüsselwort 146
GradientPaint 1095
Grammatik 85
grant-Anweisung 1408
Granularität von Threads 564
Graphics Interchange Format
1109
Graphics, Klasse 1070
Graphics2D, Klasse 1070
GraphicsEnvironment, Klasse
1083
Green-Projekt 56
Greenwich Mean Siderial Time
623
1464
GregorianCalendar, Klasse 636
Gregorianischer Kalender 635
GridBagConstraints, Klasse 956
GridBagLayout, Klasse 948, 955
GridLayout, Klasse 948, 954
Groovy 531
Groß-/Kleinschreibung 89, 242,
245
größter gemeinsamer Teiler 308
GroupLayout, Klasse 948
Grundlinie 1080
Grundton 1100
Gruppenfunktionen 1336
guard 597
guarded action 597
guarded wait 597
GUI-Builder 1339
gültig, XML 847
Gültigkeitsbereich 104
gzip 1186
GZIPInputStream, Klasse 806
GZIPOutputStream, Klasse 806
H
Halbierungssuche 722
Hashcode 507, 712
hashCode(), Object 507
Hash-Funktion 507, 712
HashMap, Klasse 662, 702
HashSet, Klasse 661, 694
Hash-Tabelle 702
Hashtable 702
Hash-Verfahren 1414
Hash-Wert 507
Haupt-Klasse 93
HEAD 1181
Header-Datei 61, 1426
HEAD-Methode 1181
Heap 182
heavyweight component 896
Helligkeit 1100
hexadezimale Zahlen 107
Hexadezimalform 106
Hibernate 1337
HierarchyEvent, Klasse 915
high level event 914
Hilfsklasse 357
Hoare 577
Holder, Klasse 217
Horcher 916
Host 1143
Host-Adresse 1161
Host-Name 1143
HotJava 56
HotSpot 355
HOUR, Calendar 642
HOUR_OF_DAY, Calendar 642
HP 57
HSB 1100
HSQLDB 1290
HTML 843, 1180
HTTP 1144, 1180
HTTP 0.9 1183
HTTP 1.0 1180
http.proxyHost 1150
http.proxyPort 1150
HttpClient 1178
HttpHandler, Schnittstelle 1187
HTTP-Header 1153
https.ProxyHost 1151
https.ProxyPort 1151
HttpServer, Klasse 1186
Hue 1100
Hyersonic 1290
Hyperbolicus Funktionen 300
Hypertext Transfer Protocol
1144, 1180
I
i18n.jar 513
IBM 1205, 1339
Ibn Mû sâ Al-Chwâ rismî 655
ICCCM 1047
Ich-Ansatz 179
ICMP 1203
ICO 1111
Icon, Schnittstelle 910–911
Identifizierer 88
Identität 194, 500
identityHashCode(), System 509
IdentityHashMap, Klasse 709
IEEE-754 Standard 108, 114, 292
IEEEremainder(), Math 303
IETF 1143–1144
if-Anweisung 129
IFC 896
if-Kaskade 133
ignorierte Statusrückgabewerte
467
IIOP 1220
Index
IllegalArgumentException 480–
481, 483
IllegalMonitorStateException
480, 596, 601
IllegalThreadStateException 548
Image, Klasse 1110
ImageIcon, Klasse 910–911
ImageIO, Klasse 1110–1111
ImageObserver, Schnittstelle
1113
Imagination 55
immutable 236
imperative Programmiersprache
92
implizites Klassenladen 513
import, Schlüsselwort 188, 229
Increment 120
Index 204, 207
Indexed-Properties 456
indexierte Variablen 207
indexOf(), String 239
IndexOutOfBoundException 209
indizierte Eigenschaft 456
InetAddress 1163
InetAddress, Klasse 1162
InetSocketAddress, Klasse 1171
infinity 293
InheritableThreadLocal, Klasse
611
Inline-Tag 434
innere Klasse 407
innere Schleife 143
InputMethodEvent, Klasse 915
InputMismatchException 273
InputStream, Klasse 767
InputStreamReader, Klasse 279,
800
InstallShields 1279
instanceof, Schlüsselwort 394,
1347
InstantiationException 371, 1362
Instanz 179
Instanzinitialisierer 353
Instanzvariable 183
instrumentalisierte Objekte 1388
int, Datentyp 101, 106, 291
Integer, Klasse 197
integraler Typ 100
Integritätsprüfung von Nachrichten 1415
Inter Client Communication Convention Manual 1047
Interaktionsdiagramm 181
Interface 64, 391, 395
interface, Schlüsselwort 396
Interface/Implementation-Pair
1015
Interface-Typen 100
intermediate container 944
internal frame 1033
Internal Server Error 1184
Internationalisierung 628
interne Fenster 1033
Internet Control Message Protocol
1203
Internet Engineering Task Force
1143–1144
Internet Foundation Classes 896
Internet Media-Types 1185
Internet Protocol 1144
Internet-Explorer 65
Inter-ORB Protocol 1220
Interrupt 557
interrupt(), Thread 557, 601
interrupted(), Thread 559
InterruptedException 529, 554,
558, 593, 601
InterruptedIOException 1173
Intersolv 1296
Intervall 141
Introspection 455, 1339
invalidate(), Component 942
InvalidClassException 822, 832
Invarianz 424
Invocation-API 1423
InvocationEvent, Klasse 1056
InvocationTargetException 1362
invoke(), Method 1369
invokeAndWait(), SwingUtilities
1055
invokeLater(), SwingUtilities 976,
1055
Invoker-Servlet 1260
IOException 466, 477
IP 1144
IP-Adressen 1161
ipconfig 1203
iPhone 58
IP-Nummer 1143
is- Methode 329
isCellEditable(), TableModel
1015, 1017
isInterrupted(), Thread 557
isNaN(), Double/Float 294
ISO Country Code 625
ISO Language Code 625
ISO-639 Code 625
ISO8859-1 85
ISO-Abkürzung 627
Ist-Eine-Art-Von-Beziehung 391
ITALIAN 626
ItemEvent, Klasse 968
ItemListener, Schnittstelle 968,
971, 974, 995
ItemSelectable, Schnittstelle 971
itemStateChanged(), ItemListener 971
Iterable, Schnittstelle 441, 664
Iterator 665
Iterator, Schnittstelle 441, 665
Ivar Jacobson 180
J
J++ 75
J/Direct 74
J2EE 68
J2ME 68
JAAS 1402, 1411
Jad 1451
Jahr 642, 651
JAI 1111
Jakarta Commons Math 317
Jakarta Taglibs Project 1247
JANUARY, Calendar 638
JAPAN 626
JAPANESE 626
Jar 1439
jar, Dienstprogramm 1435, 1439
-jar, java 1443
Jar-Datei 1155
JarFile, Klasse 816, 1156
jarsigner, Dienstprogramm 1414,
1435
JarURLConnection, Klasse 1156
Java 56, 1435
Java 2D API 897, 1074
Java Accessibility 1059
Java API for XML Parsing 855
Java Authentication and Authorization Service 1411
1465
Index
Java Authentication and Authorization Service (JAAS) 1402
Java Bean 455
Java Cryptography Architecture
1401
Java Cryptography Extension
(JCE) 1401
Java Database Connectivity 1295
Java DB 1290
Java Decompiler 1451
Java Document Object Model
855
Java Foundation Classes 896
Java Foundation Classes (JFC)
1074
Java Image Management Interface
1111
Java Look&Feel 1044
Java Management Beans 1389
Java Management Extensions
1388
Java Message Service 1227
Java Native Interface 1423
Java Network Launcher Protocol
1279
Java Object Serialization 820
Java Persistence API (JPA) 1337
Java Runtime Environment 1442
Java Secure Socket Extension
1151, 1204
Java Service Wrapper 1453
Java Virtual Machine 57
Java Virtual Machine Process
Status Tool 1444
Java Virtual Machine Statistics
Monitoring Tool 1444
java, Dienstprogramm 1437
java, Paket 230
java.awt.event, Paket 913
java.awt.geom, Paket 1075
java.beans, Paket 836
java.endorsed.dirs 519
java.ext.dirs 514
java.lang.ref, Paket 1287
java.naming.factory.initial 1310
java.net, Paket 1143
java.nio.charset, Paket 279
java.rmi.server.codebase 1220
java.rmi.useCodebaseOnly 1220
java.security 1409
java.text, Paket 275
1466
java.util.concurrent, Paket 726
java.util.concurrent.atomic, Paket
583, 608
java.util.concurrent.lock, Paket
577
java.util.jar, Paket 806, 1440
java.util.regex, Paket 262
java.util.zip, Paket 806
Java-Beans 1339
JavaBeans Activation Framework
(JAF) 748, 1196
JavaBeans Persistence 820
javac, Dienstprogramm 1435
Java-Cryptography-API 1401
JavaDoc 430
javadoc 1435
javadoc, Dienstprogramm 433
JavaDoc-Tag 1339
javah, Ant 1425
javah, Dienstprogramm 1425
JavaMail API 1196
JavaScript 64, 1276
Java-Security-Model 59
JavaServer Faces 1266
JavaServer Page 1230
JavaSoft 57
javaw, Dienstprogramm 1438
javax, Paket 230, 497
javax.annotation, Paket 541
javax.crypto, Paket 1401
javax.jws, Paket 542, 1224
javax.microedition.midlet, Paket
1286
javax.net, Paket 1204
javax.script, Paket 530
javax.sound, Paket 537
javax.sound.midi, Paket 538
javax.swing, Paket 900
javax.swing.text, Paket 1004
javax.swing.undo, Paket 1051
javax.xml.bind.annotation, Paket
542, 891
javax.xml.ws, Paket 542
Jawin 1433
JAXB 890
JAXBContext, Klasse 892
Jaxen 871, 885
JAXP 855–856
JAX-WS 1223
JBP, JavaBeans Persistence 820
JButton, Klasse 923, 927
JCA 1401
JCheckBox, Klasse 927
JCheckBoxMenuItem, Klasse 978
jCIFS 749
JColorChooser, Klasse 1038
JComboBox, Klasse 992
jconsole, Dienstprogramm 1391
jdb 1435
JDBC 1295
JDBC 1.0 1297
JDBC 2.0 API 1297
JDBC 2.0 Optional Package API
1298
JDBC 2.1 core API 1297
jdbc.drivers 1301
JDBC-ODBC Bridge Treiber 1296
JDBCRowSet, Schnittstelle 1322
JDesktopPane, Klasse 1033
JDialog, Klasse 1036
JDOM 855
JDOMResult, Klasse 889
JDOMSource, Klasse 889
JEditorPane, Klasse 1004, 1010
Jetty 1232
JFC 896
JFileChooser, Klasse 1040
JFormattedTextField, Klasse
1004, 1007
JFrame, Klasse 900, 1071
JGoodies Looks 1046
Jimi 1111
Jindent 1453
JIT 57
JLabel, Klasse 906
JLayeredPane, Klasse 1033
jlGui 538
JList, Klasse 997
jmap, Dienstprogramm 1444
JMenu, Klasse 977–978
JMenuBar, Klasse 977
JMenuItem, Klasse 927, 978
JMS 1227
JMX 1388
JMXConnector, Schnittstelle
1398
JMXConnectorServer, Klasse
1397
JNDI 1308
jndi.properties 1308
JNI 1423
Joda Time 654
Index
Joe Palrang 56
join(), Thread 561
JOIN_BEVEL, BasicStroke 1107
JOIN_MITER, BasicStroke 1107
JOIN_ROUND, BasicStroke 1107
JoinRowSet, Schnittstelle 1322
JOptionPane, Klasse 468, 1036
JOS, Java Object Serialization
820
JPA, Java Persistence API 1337
JPanel, Klasse 944
JPasswordField, Klasse 1004,
1006
JPEG 1110
JPopupMenu, Klasse 986
JProgressBar, Klasse 974, 1055
jps, Dienstprogramm 1391, 1444
JRadioButton, Klasse 927, 972–
973
JRadioButtonMenuItem, Klasse
978
JRE 1442
JRMP (Java Remote Method Protocol) 1220
JRootPane, Klasse 1032
jrunscript, Dienstprogramm 530
JScrollBar, Klasse 945, 964
JScrollPane 945
JScrollPane, Klasse 944–945,
998, 1010, 1013
JSlider, Klasse 962
JSmooth 1437
JSP 1230
JSpinner, Klasse 1002
JSplitPane, Klasse 944, 947
JSR 223 530
JSR 250 541
JSSE 1151
jstack, Dienstprogramm 1445
jstat, Dienstprogramm 1444
JSTL 1244
JTabbedPane, Klasse 944, 946
JTable, Klasse 1013
JTableHeader, Klasse 1025
JTextArea, Klasse 1004
JTextComponent, Klasse 1005
JTextField, Klasse 1004
JTextPane, Klasse 1004
JTidy 893
JToggleButton, Klasse 927, 929
JToolBar, Klasse 944, 983
JTree, Klasse 1028
JULY, Calendar 638
JUNE, Calendar 638
Just-In-Time Compiler 57
JViewport, Klasse 945
JWindow, Klasse 1035
JXPath 894
K
kanonischer Pfad 734
Kardinalität 359
kaufmännische Rundung 301
Keller 698
Kerberos 1412
Key 662
Key, Schnittstelle 1418
KeyEvent, Klasse 915, 936
KeyGenerator, Klasse 1419
KeyListener, Schnittstelle 936
KeyPairGenerator, Klasse 1419
KeySelectionManager, Schnittstelle 996
keySet(), Map 709
Keystore 1414
keytool, Dienstprogramm 1413,
1435
Kindklasse 363
Klammerpaar 150
Klasse 179
Klassendiagramm 181
Klasseneigenschaft 331
Klassenhierarchie 364
Klasseninitialisierer 335
Klassenkonzept 64
Klassenlader 59, 512, 1403
Klassen-Literal 498
Klassenmethode 151
Klassenobjekte 498
Klassen-Typen 100
Klassenvariable, Initialisierung
351
Klonen 504
Kodierung, Zeichen 278
Kollision, Signatur 1415
Kollisionsangriff 1415
Kommandozeilenparameter 227
Kommaoperator 143
Kommentar 93
Komplement 167
komplexe Zahl 317
Kompressionsfunktion 1415
Kompressionsstufe 1125
Komprimierungsfaktor 1110
Konkatenation 236
konkrete Klasse 391
konstante Zeichenkette 236
Konstantenpool 238
konstruktive Flächengeometrie
1091
Konstruktor 186, 342
Konstruktoraufruf 182
Konstruktoren in Vererbung 367
Konstruktorweiterleitung 367
Kontextmenü 986
Kontraktionsfunktion 1415
Kontrollfeldgruppe 972
Kontrollstrukturen 128
Kopf 148
Kopfdefinition 846
KOREA 626
KOREAN 626
Kouznetsov, Pavel 1451
kovarianter Rückgabetyp 380
Kovarianz bei Arrays 381
Kreiszahl 297
kritischer Abschnitt 574
kryptografische Prüfsumme 1415
ktoolbar, Dienstprogramm 1283
kubische Kurvensegmente 1091
Kupfersäule 164
Kurven 1091
Kurzschlussoperator 119
L
Länge des Strings 238
lastIndexOf(), String 240
Last-Modified 1185
Latin-1 799
Laufwerksname 738
Laufzeitumgebung 57
launch4j 1437
LayoutManager, Schnittstelle 949
lazy activation 1221
LCDUI 1287
LD_LIBRARY_PATH 1429
leading 1086
Lease 1218
Lebensdauer 104
leere Anweisung 99
leerer Block 99
1467
Index
leerer String 248
Leer-String 249
Leerzeichen 274
Leerzeichen entfernen 246
Lempel-Ziv Kodierung 1186
length(), String 238
Lexikalik 85
lib/security 1409
LIFO 698
lightweight component 898
line joins 1105, 1107
line.separator 522, 1406
Line2D, Klasse 1089
lineare Algebra 317
lineare Kongruenzen 306
LinearGradientPaint 1095
LineBorder, Klasse 933
LineMetrics, Klasse 1087
LineNumberReader, Klasse 791
lineTo(), GeneralPath 1091
Linie 1075
Linienende 1106
Linien-Pattern 1105
Linieverbindung 1107
LinkedHashSet, Klasse 698
LinkedList, Klasse 661–662, 669,
680
Linking 512
linksassoziativ 122
Liskov'sches Substitutionsprinzip 374
Liskov, Barbara 374
List, Schnittstelle 661, 669
ListCellRenderer, Schnittstelle
1002
Listen 669
Listen füllen 720
Listener 451, 916
ListIterator, Schnittstelle 674
ListSelectionEvent, Klasse 999–
1000
ListSelectionListener, Schnittstelle 999–1000
ListSelectionModel, Schnittstelle
1025
Literal 108
Load Factor 713
loadClass(), ClassLoader 515
loadLibrary(), System 1424
Locale, Klasse 625
LocateRegistry, Klasse 1214
1468
Location, Response-Header 1185
Lock 577, 583
lock(), Lock 578
Locking 747
log(), Math 303
Log4j 1399
logClass 1217
Logger, Klasse 1385
Logging, RMI 1217
Login-Modul 1412
logisch atomar 595
logischer Operator 119
logisches Komplement 120
logisches Und 121
logisches Xor 121
lokale Klasse 413
lokale Objekte 1211
lokaler Host 1164
lokalisierte Zahl 273
Lokalisierung 628
long 106
LONG, DateFormat 649
long, Datentyp 101
Long, Klasse 197
low level event 914
lower bound wildcard 425
Luxor 1065
LU-Zerlegung 317
LZ77 1186
M
MAC 1415
MAC-Adresse 1203
magic number 337
magische Zahl 337
magische Zahlenwerte 1349
Mail User Agent 1195
main() 94
main()-Funktion 72
Main-Class 1442
Makro 61
MalformedURLException 1146
Management Interface 1389
ManagementFactory, Klasse 1393
MANIFEST.MF 1442
Manipulation Detection Code
1415
Mantelsklasse 195
Mantisse 292
Map, Schnittstelle 657, 662, 702
Map.Entry, Klasse 710
MARCH, Calendar 638
marker interface 398
Markierungsschnittstelle 398,
824
Marshaller, Schnittstelle 892
marshalling 1208
Matcher, Klasse 262
matches(), Pattern 262
matches(), String 262
MatchResult, Schnittstelle 264
Math, Klasse 297
MathContext, Klasse 315
Matisse 948
MatteBorder, Klasse 933
Mausrad 938
maven 1446
max(), Collections 688
max(), Math 299
MAX_PRIORITY, Thread 563
MAX_RADIX 234
Maximalwert 1337
Maximum 173, 298
MAY, Calendar 638
MBean 1388
MBean-Server 1388
McNealy, Scott 56
MD 1414
MD2 1415
MD4 1415
MD5 1415
MDC 1415
MediaTracker, Klasse 1126
MEDIUM, DateFormat 649
Megginson, David 854
mehrdimensionales Array 213
Mehrfachvererbung 399
Mehrfachverzweigung 132
member class 409
memory leak 355
Memory Map 1444
Menü 976
Menübalken 977
Menüeintrag 977
Menütrennlinie 979
Merant 1296
Merge-Sort 690
Meridian 623
MESA 55
Message Authentication Code
1415
Index
Message Integrity Check 1415
Message Queues 1227
Message Store 1195
Message Transfer Agent 1195
Message Transfer System 1195
Message-Digest 1414
MessageDigest, Klasse 1416
MessageFormat, Klasse 284, 287
Metadaten 1183, 1328
META-INF/MANIFEST.MF 1442
Meta-Information 1185
Meta-Objekte 1341
Meta-Programming 1339
Method, Klasse 1355
Methode des Aufrufes 1181
Methoden 94, 147
überladen 158
Methodenaufruf 322
Methodenkopf 148
Methodenrumpf 148
MEZ 632
MIC 1415
Microsoft 65
Microsoft Access 1292
Microsoft Development Kit 74
Microsoft SQL Server 1292
Middleware 1209–1210
MIDI 538
MidiSystem, Klasse 538
Midlet 1286
MIDP (Mobile Information Device
Profile) 1282
MILLISECOND, Calendar 642
Millisekunden 642
MIME 1195
MimeMultipart, javax.mail 1201
MIME-Nachrichten 1183
MIME-Typ 1154
min(), Collections 688
min(), Math 299
MIN_PRIORITY, Thread 563
MIN_RADIX 234
MIN_VALUE 295
Minimum 173
MINUTE, Calendar 642
Mitgliedsklasse 409
Mitteleuropäische Zeit 632
mitteleuropäische Zeit 633
Mnemonic 981
Mobile Information Device Profile
(MIDP) 1282
modal 1036
Model 991
Model MBeans 1389
Model-View-Controller 448, 990
Modifizierer 98, 1349
modifiziertes UTF-8 753
Modulo 114
Monat 642
Mönch 165
Monitor 577
monitorenter 577
monitorexit 577
Monitoring 1387
MONTH, Calendar 642
mouse wheel 938
MouseEvent, Klasse 915
MouseInfo, Klasse 1064
MouseListener, Schnittstelle 916
MouseMotionListener, Schnittstelle 916
MouseWheelEvent, Klasse 938
Moved Permanently 1184
Moved Temporarily 1184
MS 1195
MTA 1195
MTS 1195
MUA 1195
multicast 74
Multicast, Bean 454
Multicast-Kommunikation 1204
Multilevel continue 146
MULTILINE, Pattern 264
Multi-Map 715
Multiple Choices 1184
MULTIPLE_INTERVAL_SELECTION, ListSelectionModel
1000
Multiplikation 112
Multiplizität 359
Multipurpose Internet Mail
Extensions 1195
multitaskingfähig 543
multithreaded 544
Muster 262
MutableTreeNode, Schnittstelle
1028
Mutex 577
MVC 990
MXBeans 1389
MySQL 1291
N
Namensdienst 1207, 1213
Namensraum 852
Naming 1216–1217
NaN 293, 295
nanoTime(), System 525
narrowing conversion 123
native Methode 1423
Native Protocol All-Java Driver
1297
native Threads 544
native, Schlüsselwort 1424
native2ascii, Dienstprogramm,
279
Native-API Java Driver 1297
NativeCall 1433
nativer Compiler 1436
natural ordering 685
natürliche Ordnung 685
NavigableMap, Schnittstelle 662,
704
NavigableSet, Schnittstelle 696
Navigation 935
nearest neighbor algorithm 1122
Nebeneffekt 322
N-Eck 1078
NEGATIVE_INFINITY 295
negatives Vorzeichen 110
Nelson 1205
nested exception 485
nested top-level class 408
NetBeans 74
NetPermission 1410
netstat 1172
Network Filesystem 1189
Network Information Services
1143
NetworkInterface, Klasse 1165
Netz-Protoll All-Java Driver 1297
new line 522
new, Schlüsselwort 182, 342,
1361
newInstance() 371
newInstance(), Array 1351
newInstance(), Constructor 1361
newLine(), BufferedWriter 789
NFS 1189
nicht ausführend 593
nicht geprüfte Ausnahme 480
nicht-primitives Feld 212
1469
Index
nicht-rechteckiges Feld 214
NIS 1143
No Content 1184
NO_SUCH_PAGE, Printable 1137
No-Arg-Konstruktor 186
NoClassDefFoundError 1342
non-static method-Fehlermeldung 151
Normalizer, Klasse 262
Normalverteilung 307
NoSuchAlgorithmException
1417
NoSuchElementException 666,
701
NoSuchProviderException 1417
Not Found 1184
Not Implemented 1184
Not Modified 1184
Not-a-Number 293, 295
Notation 180
notify(), Object 592, 600
notifyAll() 595
NotSerializableException 822,
824, 826
NOVEMBER, Calendar 638
nowarn 1436
NULL 465
null, Schlüsselwort 183, 188
NULL, SQL 1317
NullPointerException 189, 209,
480
Null-Referenz 188
Null-String 249
Number, Klasse 197
NumberFormat, Klasse 197, 284–
285
NumberFormatException 251,
468
numeric promotion 112
numerische Umwandlung 112
numerischer Typ 111
O
Oak 55
Oberklasse 363
Oberklasse finden 1347
Oberlänge 1086
Obfuscator 1343, 1451
Object Management Group 180,
1207, 1220
1470
Object Serialization Stream
Protocol 827
Object, Klasse 363, 498
ObjectInputStream, Klasse 822
Objective-C 64
ObjectName, Klasse 1395
ObjectOutputStream, Klasse 821
ObjectStreamField, Klasse 827
Objektansatz 179
Objektgleichheit 500
Objektidentifikation 498
objektorientiert 58
objektorientierter Ansatz 64
Objektorientierung 98
Objektvariable 183
Objektvariable, Initialisierung
350
Observable, Klasse 448
Observer, Schnittstelle 448
Observer/Observable 448
Observer-Pattern 990
OCTOBER, Calendar 638
ODBC 1292, 1295–1296
ODBC-Datenquellen-Administrator 1292
Oder 119
off-by-one error 141
OK 1184
Oktalform 106
Olson, Ken 1281
OMG (Object Management
Group) 180, 1207
OO-Methode 180
opak 943
Open Database Connectivity
Standard 1296
Open MBeans 1389
openStream(), URL 1148
Operator 111
operator precedence 120
Optionsfeld 972
Oracle 1291
OracleDriver 1302
Ordinalzahl, Aufzählung 426
Ordinalzahl, Enum 426
org.jdom, Paket 870
org.omg, Paket 497
Ostersonntag 639
OutOfMemoryError 182, 505
OutputStream, Klasse 764
OutputStreamWriter, Klasse 279,
799
OverlayLayout, Klasse 962
P
P2P 1227
Pack200 806
Package, Klasse 1373
package, Schlüsselwort 229
PAGE_EXISTS, Printable 1137
paint(), Frame 1069
Paint, Schnittstelle 1095
paintComponent() 1071
Paket 187, 1143
Paketsichtbarkeit 324
PalmOS 1281
PalmPilot 68
Palmsonntag 640
Parameter 152
Parameterliste 148, 150
Parameterübergabemechanismus 152
parametrisierter Typ 419
parseBoolean(), Boolean 251
Parsed Character Data 848
parseDouble(), Double 251
ParseException 285, 653
parseInt(), Integer 198, 251, 468
parseObject(), Format 285
partiell abstrakte Klasse 392
Passionssonntag 640
PATH 72
Patrick Naughton 56
Pattern, Klasse 262
Payne, Jonathan 56
PCDATA 848
p-code 57
PDA 68
PDAP 1283
Peer-Elemente 1054
Peer-Klassen 895
Permissions 1410
PersistenceDelegate, Klasse 837
Persistenz 455
Personal Digital Assistant Profile
1283
Personal Java 68
Pfad 1091
Pfingstsonntag 640
PicoJava 58
Index
Picture Element 1073
PipedInputStream, Klasse 801
PipedOutputStream, Klasse 801
PipedReader, Klasse 801
PipedWriter, Klasse 801
pissing on at every opportunity
75
Pixel 1073
Plattenspeicher 739
Pluggable Authentication Module
(PAM) 1412
Pluggable Look and Feel 897
Plugins, Eclipse 82
PocketPC 1282
Point, Klasse 179, 182
Pointer 59
PointerInfo, Klasse 1064
Point-to-Point 1227
Polar-Methode 307
Policy-Datei 1408
policytool, Dienstprogramm
1410, 1435
Polygon 1077
Polygon, Klasse 1078, 1089
Polylines 1077
Polymorphie 385
Pommes-Bude 50
POP before send 1200
POP3 1196
Popup-Menü 986
Porphyr 164
Port 1234 1172
Port, RMI-Namensdienst 1215
Port-Adresse 1167
Position des Fensters 903
POSITIVE_INFINITY 295
POST 1181
Post-Dekrement 116
Post-Inkrement 116
POST-Methode 1159, 1180
Potenz 303
Prä-Dekrement 116
Präfix 242
Präfix/Postfix 116
Pragma 1185
Prä-Inkrement 116
Preferences, Klasse 532
Preimage-Angriffe 1415
PreparedStatement, Schnittstelle
1310, 1326
primitiver Type 100
Primzahlen 730
Principal 1408, 1412
print() 159, 775
Printable, Schnittstelle 1137
PrinterJob, Klasse 1137
printf() 97, 775
printf(), PrintWriter/PrintStream
282
PrintJob, Klasse 1137
println(), print() 96, 775
PrintService, Schnittstelle 1138
printStackTrace() 467
PrintStream 775
PrintWriter 775
Priorität, Thread 563
Prioritätswarteschlange 563
PriorityQueue, Klasse 661
private, Schlüsselwort 325, 1349
PrivateKey, Schnittstelle 1418
Privatsphäre 324
Process, Klasse 529
ProcessBuilder, Klasse 526
Profil, Java ME 1282
Profiling 525
Profiling-Informationen 1438
Programm 93
Programmicon 1116
Programmieren gegen Schnittstellen 399
ProGuard 1451
Prolog 93
Properties 455, 715
Properties, Bean 455
Properties, Klasse 521, 715
Property 329
PropertyChangeEvent, Klasse
457, 463, 943
PropertyChangeListener, Schnittstelle 457
PropertyDescriptor, Klasse 1358
PropertyPermission 1410
Property-Sheet 455
PropertyVetoException 460
Proposed Standard 1144
protected, Schlüsselwort 327,
366, 1349
Protocol Handler 1154
Protocols 64
Protokoll 1144
Protokoll-Handler 1154
Proxy 1205
Proxy-Authenticate, ResponseHeader 1185
Proxy-Authorization 1158
Proxy-Server 1150
Prozess 543
Pseudo-Primzahltest 308
Public, Response-Header 1185
public, Schlüsselwort 324, 1349
PublicKey, Schnittstelle 1418
Publish-Subscribe 1227
Pulldown-Menü 976
Punktoperator 184
pure abstrakte Klasse 392
PushbackInputStream, Klasse 792
PushbackReader, Klasse 792
PUT 1181
put(), Map 704
Q
qNaNs 295
QuadCurve2D, Klasse 1089
quadratische Kurvensegmente
1091
Quadratwurzel 302
quadTo(), GeneralPath 1091
QuantumDB 1293
Quartz 621
Quasiparallelität 543
Quellcodeverschönerer 1452
Query-String 1159
Queue, Schnittstelle 661, 700
Quicksort 690
Quiet NaN 295
Quoted Printing Encoding 1196
R
race condition 575
race hazard 575
RadialGradientPaint 1095
Rahmen 932
random(), Math 212, 304
Random, Klasse 306
RandomAccess, Schnittstelle 677
RandomAccessFile, Klasse 466,
751
Rang eines Operators 120
Range-Checking 61
Rangordnung 120
Raw-Type 422
1471
Index
Reader, Klasse 773
readLine(), BufferedReader 791
readLine(), RandomAccessFile
466
readObject(), ObjectInputStream
822
readPassword() 781
readResolve() 830
readUTF(), RandomAccessFile
753
ReadWriteLock, Schnittstelle 580
rebind(), Registry 1215
Rechenungenauigkeit 138
rechtsassoziativ 122
Record Management System
1287
Rectangle2D, Klasse 1089
RectangularShape, Klasse 1089
reentrant 588
ReentrantLock, Klasse 578
ReentrantLock, Schnittstelle 593
ReentrantReadWriteLock, Klasse
581
Reference Concrete Syntax 845
referenced-Meldung 1218
Referenz 59
Referenzierung 128
Referenztyp 100, 111
Referenztyp, Vergleich mit ==
193
Referenzvariable 183
Reflection 1339
ReflectPermission 1410
reflexive Assoziation 359
reg 536
regionMatches(), String 242
Registry 532, 1207, 1213
REGISTRY_PORT 1214
REGISTRY_PORT, Registry 1214
reguläre Ausdrücke 262
Reihung 204
reine abstrakte Klasse 392
Rekursionsform 163
rekursive Assoziation 359
rekursive Funktion 162
relationale Datenbanksysteme
1295
Relationaler Operator 118
Remainder Operator 113
Remote Manager 1388
Remote Object Activation 1221
1472
Remote Procedure Call 1207
Remote, Schnittstelle 1211
RenderedImage, Schnittstelle
1123
Rendering-Algorithmus 1134
Renderpack Pipelines 1027
Rendezvous 560, 562
repaint() 1072
replace(), String 246
replaceAll(), Collections 720
replaceAll(), String 247
replaceFirst(), String 247
ReplicateScaleFilter, Klasse 1122
Request 1181
Request For Comment 1144
Request Header 1183
requestFocusInWindow(), JComponent 935
reservierte Schlüsselwörter 89
ResourceBundle, Klasse 629
Response-Header 1183, 1185
Rest der Division 304
Restwertoperator 112–113, 303
Result, Schnittstelle 889
Resultat 111
ResultSet, Schnittstelle 1312
ResultSetMetaData, Schnittstelle
1329
resume(), Thread 563
RetentionPolicy, Aufzählung
1380
Re-throwing 484
Retry-After, Response-Header
1185
return, Schlüsselwort 153, 216
revalidate(), JComponent 942
RFC 1144
RFC 1521 280
RFC 1952 1186
RFC 2616 1180
RGB 1100
Rhino 530
Rich Text Format 1010
rint(), Math 301
Ritchie, Dennis M. 70
RMI 1207
RMI Wire Protocol 1208
rmi:// 1216
rmic, Dienstprogramm 1213
RMIClassLoader, Klasse 1220
rmid, Dienstprogramm 1222
RMI-Klassenlader 1220
RMI-Logging 1217
rmiregistry, Dienstprogramm
1214, 1310
RMI-Transportschicht 1208
Robot, Klasse 1060, 1062
Rollbalken 962
Rollenbasierte Rechtevergabe
1411
Rollrads 938
Ron Rivest 1415
Rotation 1134
round(), Math 301
RoundingMode, Aufzählung 316
RoundRectangle2D, Klasse 1089
Router 1143
RowFilter, Klasse 1027
RowSet, Schnittstelle 1321
RPC 1207
rt.jar 513
RTF 51, 1010
Rückgabetyp 148
Rückgabewert 150
Rumpf 148
run(), Runnable 546
Runden 300
Rundungsfehler 114
Rundungsmodi, BigDecimal 315
runFinalizersOnExit(), System
512
Runnable, Schnittstelle 415, 546
Runtime 526
Runtime Packages 1401
RuntimeException 479
Run-Time-Interpreter 57
RuntimePermission 1410
r-Wert 111
S
Sandbox 1403
Saturation 1100
SAX 854
SAXBuilder, Klasse 872
SAXParser, Klasse 866
SCALE_AREA_AVERAGING,
Image 1121
SCALE_DEFAULT, Image 1121
SCALE_FAST, Image 1121
SCALE_REPLICATE, Image 1121
SCALE_SMOOTH, Image 1121
Index
Scanner, Klasse 268
Schablonen-Muster 766
Schaltjahr 155, 624
ScheduledThreadPoolExecutor,
Klasse 567, 572
Scheduler 543, 573
Schema 849
Scherung 1134
Schieberegler 962
Schlange 661
Schleifen 136
Schleifenbedingung 137–138
Schleifen-Inkrement 140
Schleifentest 140
Schleifenzähler 141
Schlüssel 662
Schlüsselpaare 1413
Schlüsselspeicher 1414
Schlüsselwörter 89
Schnittstelle 64, 395
Schnittstellen-Typen 100
Schriftlinie 1080
Schurken 623
schwergewichtige Komponente
896
Schwyzerdütsch 631
Scope 104
Screen_Updater 566
Screenshot 1063
ScriptEngine, Schnittstelle 531
ScriptEngineManager, Klasse 531
Scriptlets 1251
Scrollable, Schnittstelle 945
Scrollbar 962
ScrollPaneLayout, Klasse 962
sealing, Jar 412
SECOND, Calendar 642
SecretKey, Schnittstelle 1418
SecretKeySpec, Klasse 1420
Secure Hash Algorithm 1415
Secure Hash Standard 1415
Secure Sockets Layer 1204
SecureRandom, Klasse 306
Security Manager 1403
SecurityException 1408
Security-Manager 59
SecurityManager 1267
SecurityManager, Klasse 1403–
1404
SecurityPermission 1410
Seed 306–307
Seiteneffekt 322
Sekunden 642
Selbstbeobachtung 455
Semantik 85
semantisches Ereignis 914
Semaphore, Klasse 603
Separator 91
SEPTEMBER, Calendar 638
SEQUEL 1333
Sequence, Klasse 539
SequenceInputStream, Klasse 769
Sequencer, Schnittstelle 538–539
Sequenz 656, 661
Sequenzdiagramm 181
Serializable, Schnittstelle 824
SerializablePermission 1410
serialPersistentFields 827
serialver, Kommandozeilenprogramm 834
serialVersionUID 833
Server 1167, 1207
Server, Response-Header 1185
ServerSocket, Klasse 1172
Service Unavailable 1184
ServiceLoader, Klasse 1301
Service-Provider Implementation 497
Session, Klasse 1196, 1199
Set, Schnittstelle 661, 692
setBorder(), JComponent 932
setContentType(), JEditorPane
1010
setDefaultCloseOperation(),
JFrame 901, 922
setDefaultRenderer(), JTable
1022
setDoInput(), URLConnection
1153
setDoOutput(), URLConnection
1153
setFont(), Graphics 1081
setLayout(), Container 948
setLookAndFeel(), UIManager
1044
setModel(), JSpinner 1002
setModel(), JTable 1017
setPaint(), Graphics2D 1096
setPriority(), Thread 563
setProperty(), Properties 715
setRenderingHint(), Graphics2D
1089
setSize(), Window 903
Setter 329
setText(), JButton 924
setText(), JLabel 907
setText(), JTextComponent 1005
Set-Top-Boxen 56
setVisible(), Window 903
SGML 844
SHA 1415
Shallow Copy 712
Shamir, Adi 1415
Shape, Schnittstelle 1088–1089
shared objects 1427
ShellFolder, Klasse 737
Sheridan, Mike 56
Shift 120
Shift-Operator 169
SHORT, DateFormat 649
short, Datentyp 101, 106, 291
Short, Klasse 197
Short-Circuit-Operator 119
showConfirmDialog(), JOptionPane 1038
showMessageDialog(), JOptionPane 1038
showOptionDialog(), JOptionPane
1038
SHS 1415
Shutdown-Hook 621
Sicherheitsmanager 1403, 1407
Sichtbarkeit 104, 324, 366
Sichtbarkeitsmodifizierer 324
signal(), Condition 593
signaling NaN 295
Signierung 1408, 1412
Simple API for XML Parsing 854
Simple Mail Transfer Protocol
1195
SimpleDateFormat, Klasse 647
SimpleTimeZone, Klasse 633
SIMPLIFIED_CHINESE 626
SIMULA 64
Simula-67 177
sin(), Math 299
Single Inheritance 365
SINGLE_INTERVAL_SELECTION,
ListSelectionModel 1000
SINGLE_SELECTION, ListSelectionModel 1000
Singleton 357, 724
sinh(), Math 300
1473
Index
Sinus 299
sizeof 128
Skalierung 1134
Skipjack 1415
Skript-Engine 530
Slash 732
sleep(), Thread 553
slider, Schieberegler 962
Slivka, Ben 75
Smalltalk 58, 177
Smart-Card 1412
SMB (Server Message Block) 749
Smiley 87
SMTP 1195
SMTP-Server 1196
sNaN 295
SOAP 1222
SOCK_DGRAM 1203
SOCK_STREAM 1203
Socket, Klasse 1167
SocketPermission 1410
Sockets 1166
SOCKS 1151
SoftBevelBorder, Klasse 933
Sommer-/Winterzeit 632
Sommerzeit 633
Sommerzeitabweichung 643
sort(), Arrays 223, 687
sort(), Collections 689
SortedMap, Schnittstelle 704
SortedSet, Schnittstelle 697
sortieren 689
Soundbank 538
Source, Schnittstelle 889
Source-Code Beautifier 1452
späte dynamische Bindung 385
SpinnerDateModel, Klasse 1002
SpinnerListModel, Klasse 1002
SpinnerModel, Schnittstelle 1002
SPI-Pakete 497
Splash-Screen 1117
split(), Pattern 267
split(), String 266
SpringLayout, Klasse 948
Sprungmarken 146
SQL 1333
SQL 2 1333
SQLException 1306, 1318
SQLWarning, Klasse 1318
SQuirreL 1293
SSL 1204
1474
SSLSocket, Klasse 1204
SSLSocketFactory, Klasse 1204
stabil sortieren 689
Stabile Sortieralgorithmen 691
Stack 698
Stack, Klasse 698
Stack-Inhalt 488
Stack-Trace 486
StackTraceElement, Klasse 487
Standard Extension API 497
Standard Generalized Markup
Language 844
Standard MBeans 1388
Standard Tag Library 1244
Standard Widget Toolkit 1066
Standardberechtigungen 1409
Standard-Konstruktor 186, 343
Standardserialisierung 820
Stapelspeicher 698
Star Seven 56
start(), Thread 547
startsWith(), String 242
Statement, Schnittstelle 1310
statements 92
static final 396
static, Schlüsselwort 99, 151, 331
statische Eigenschaft 331
statische innere Klasse 408
statische Methode 151
Statischer Block 335
statisches Import 231
Statusanzeige 974
Statuscode 1183
Statuszeile 1183
StAX 856
Stellvertreterobjekt 1205, 1213
Sternzeit 623
Steuerelemente 895
stilles NaN 295
STL Bibliothek 690
stop(), Thread 557
Store-and-Forward 1195
StreamEncoder 799
StreamFilter, Schnittstelle 861
StreamTokenizer, Klasse 838
streng-typisiert 100
strictfp, Schlüsselwort 305
StrictMath, Klasse 305
String 96, 234
StringBuffer, Klasse 236, 252
StringBuilder, Klasse 236, 252
StringIndexOutOfBoundsException 242–243
Stringkonkatenation 120
String-Literale 236
StringReader, Klasse 763, 784
Stringteil vergleichen 242
Stringteile extrahieren 242
StringTokenizer, Klasse 273
StringWriter, Klasse 782
Stroke, Schnittstelle 1105
Stroustrup, Bjarne 178
Structured English Query
Language 1333
Struts 1266
Subinterface 403
Subject 1412
Subklasse 363
Subprotokoll 1304
Substitutionsprinzip 374
substring(), String 243
Subtraktion 112
Suffix 242
SUID 834
Summe aller Einträge 1337
sun, Paket 230
sun.boot.class.path 514
sun.jdbc.odbc.JdbcOdbcDriver
1302
sun.nio.cs 799
SunWorld 56
super() 369, 371
super, Generics 423
super, Schlüsselwort 371, 378
Superklasse 363
Surrogate-Paar 86
suspend(), Thread 563
SWIG 1433
swing.properties 1044
SwingUtilities, Klasse 1055
SwingWorker, Klasse 1056
SwingWT 1066
switch-Anweisung 133
Swixml 1065
SWT 1066
symbolische Konstante 336
Symbolleiste 983
sync() 762
Synchronisation 512, 573
synchronized, Schlüsselwort 577,
582
SynerJ 74
Index
Syntax 85
System.err 97, 779
System.in 527, 767, 779
System.out 97, 779
SystemColor, Klasse 1095, 1101
Systemeigenschaften 72, 521
Systemfarben 1101
System-Klassenlader 515
SystemTray, Klasse 989
T
TableCellEditor, Schnittstelle
1023
TableCellRenderer, Schnittstelle
1019
TableColumn, Klasse 1024
TableLayout, Klasse 962
TableModel, Schnittstelle 1014,
1024
TableModelEvent, Klasse 1018
TableModelListener, Schnittstelle 1014
TableRowSorter, Klasse 1027
Tabulator 274
Tag 642, 843
Tag des Jahres 642
Tage im Monat 646
Tagesdatum 644
Taglib 1244
TagLib-Deskriptoren 1244
TAI 624
TAIWAN 626
Taj Mahal 64
tan(), Math 299
Tangens 299
tangle 431
Tango Desktop Projekt 911
tanh(), Math 300
Tar-Archive 806
Tastatur-Shortcut 981
Tastenkürzel 981
TCP 1189
TCP/IP 1166
Tear-Off-Menü 978
Teletubbies 1161
Template-Code 1236
Template-Pattern 766
terminiert 564
TextArea, Klasse 1008
TextLayout, Klasse 1087
TexturePaint 1095
Textverarbeitung 50
this und Vererbung 416
this$0, innere Klasse 412
this() 371
this(), Beschränkungen 349
this(), Konstruktoraufruf 348
this-Referenz 322, 371
this-Referenz, innere Klasse 410
Thread 543
thread local storage (TLS) 609
Thread, Klasse 415, 547
ThreadDeath, Klasse 559
ThreadGroup, Klasse 612
Threadgruppe 615
ThreadLocal, Klasse 609
thread-lokale Variablen 609
Thread-Pool 567
ThreadPoolExecutor, Klasse 567
Threads, Zustände 553
Throwable, Klasse 476
throws 469
Tick Marks 962
tiefe Kopie, clone() 507
Tiefe Objektkopien 831
Tim Berner-Lee 1180
timeout 1208
Timer, Klasse 619
Timer, Swing-Klasse 1064
TimerTask, Klasse 619
Timestamp, Klasse 1316
TimeZone, Klasse 632
Titelleiste 902
TitledBorder, Klasse 933
TLS 1204
toArray(), Collection 682
toCharArray(), String 207
tödliche Umarmung 590
Token 90, 274
toLowerCase(), Character 234
toLowerCase(), String 245
Tomcat 1232
Toolkit, Klasse 899
TooManyListenersException 454
Topic, JMS 1227
Toplevel-Container 900
Top-Level-Klassen 408
toString(), Arrays 224
toString(), Integer 199
toString(), Object 376, 498
toString(), Point 185
toUpperCase(), Character 234
toUpperCase(), String 245
Transferable, Schnittstelle 1047
Transfer-Encoding 1185
TransferHandler, Klasse 1050
Transformationen 1095
transient, Schlüsselwort 827
translate(), Graphics 1130
Transparency, Schnittstelle 1096
TransparentLayout 961
Transport Layer Security 1204
Transportschicht 1208
TrayIcon, Klasse 989
TreeMap, Klasse 656, 662, 702
TreeModel, Schnittstelle 1028,
1030
TreeNode, Schnittstelle 1030
TreeSelectionListener, Schnittstelle 1029
TreeSet, Klasse 695
Trennzeichen 90, 266
trim(), String 246
true 101
TrueType-Zeichensatz 1084
TrueZIP 806
try 465
Tupel 1289
Türme von Hanoi 164
typ erasure 421
Typanpassung 122
TYPE_INT_RGB, BufferedImage
1119
TYPE_SCROLL_INSENSITIVE,
ResultSet 1318
Typecast 122
Types, Klasse 1314
Typvariable 419
Typvergleich 121
U
Überblendung, Grafik 1104
überdecken, Methoden 387
überladen 97
überladene Methode 158
überladener Operator 62
überladenes Plus 127
überlagert, Methode 376
Überlauf 296
überschreiben, Methoden 376
Übersetzer 95
1475
Index
überwachtes Warten 597
Uboxing 200
UCSD-Pascal 57
UDP 1189
UDP-Protokoll 1188
UIDefaults, Klasse 908
UI-Delegate 940
UIManager, Klasse 1044
UK 626
Umgebungsvariablen, Betriebssystem 524
Umkehrfunktionen 299
UML 180
Umlaut 86
Umrisslinie 1105
Umrisslinie, Stroke 1095
unärer Operator 110
unäres Minus 115
unäres Plus/Minus 120
Unauthorized 1184
unbenanntes Paket 230
UncaughtExceptionHandler,
Schnittstelle 556
unchecked 541
Und 119
UNDECIMBER, Calendar 638
Undo/Redo 1051
UndoableEditEvent, Klasse 1052
UndoManager, Klasse 1051
Unendlich 293
Unicast, Beans 454
UnicastRemoteObject, Klasse
1215
Unicast-Verbindung 1204
Unicode escapes 86
UNICODE_CASE, Pattern 264
Unicode-Zeichen 85
unidirektionale Beziehung 359
Unified I/O 755
Unified Method 180
Uniform Resource Locater 1144
Universal Time 623
Unix-Crypt 1418
UnknownHostException 1168
unlock(), Lock 578
Unmarshaller, Schnittstelle 892
unnamed package 230
UnsatisfiedLinkError 1424
UnsupportedOperationException 480, 486, 660, 667,
681, 723
1476
Unterklasse 363
Unterlänge 1086
Untermenü 977
Unzahl 112
Upgrade 1185
upper bound wildcard 425
URL 1144
URL, Klasse 1144
URLClassLoader, Klasse 516
URLConnection, Klasse 1151
URLDecoder, Klasse 1160
URLEncoder, Klasse 1159
US 626
Use-Cases-Diagramm 181
user.timezone 638
UTC 624
UTF-16 846
UTF-16 Kodierung 86
UTF-8 846
UTF-8 Kodierung 753
Utility-Klasse 357
uuencode 1195
V
valid, XML 847
Value 662
valueOf() 196
valueOf(), String 250
values(), Map 709
Varargs 217
variable Argumentanzahl 217
Variablendeklaration 102
Variableninitialisierung 387
Vary, Response-Header 1185
Vector, Klasse 669
veränderbare Zeichenketten 252
verbindungsloses Protokoll 1188
verbindungsorientiert 1188
verbose 1436, 1438
Verbundoperator 115
verdecken von Variablen 322
vererbte Konstanten 404
Vererbung 363
Vergleich 241
Vergleichsoperator 118
Vergleichsstring 242
verkettete Liste 657, 680
Verklemmung 544
Verlaufsbalken 974
Verschiebeoperator 169
Verschiebung 1134
Verzeichnis anlegen 740
Verzeichnis umbenennen 740
Vetorecht 456
Via 1185
Video-Übertragungen 1129
View 991
ViewPortLayout, Klasse 962
virtuelle Maschine 57
Visual Age for Java 73
Visual Basic 246
void, Schlüsselwort 151
volatile, Schlüsselwort 606
VolatileImage, Klasse 1129
Vorschaubild 1111
Vorzeichenerweiterung 120
Vorzeichenumkehr 115
W
Wahrheitswert 100
wait(), Object 592, 600
War-Archiv 1234
Warning, Response-Header 1185
Warning:Applet Window 1408
Watson, Thomas 1205
WAV 538
weave 431
WEB 431
Web Application Security 1266
Web-Applets 56
Webbrowser 1011
WebRowSet, Schnittstelle 1322–
1323
WebRunner 56
Webstart 1279
Wechselknopf 929
WEEK_OF_MONTH, Calendar
642
WEEK_OF_YEAR, Calendar 642
Weichzeichnen 1075, 1134
Well-Known System Ports 1167
Wertebereich 328
Werte-Objekt 196
Wertoperation 110
Wertübergabe 152
Wettlaufsituation 575
while-Schleife 136
WHITE, Color 1098
White-Space 90
widening conversion 123
Index
Widgets 895
Wiederverwendung per CopyUnd-Paste 127
Wildcard 425
Wilde 1267
Win32-API 74
WinCE 1281
WIND_NON_ZERO, GeneralPath 1093
Winding Rule 1092
windowClosed(), WindowListener 921
windowClosing(), WindowListener 921
WindowEvent, Klasse 918
WindowListener, Schnittstelle
916
Windows Icon-Format 1111
Windows XP 1267
Windows-NT Konsole 278
Windows-Registry 536
Windungsregel 1092
Winkelfunktionen 299
WinZip 69
Wireless Toolkit 1283
wissenschaftliche Notation 108
Woche 642
Woche des Monats 642
wohlgeformt 845
WORA 65
Word 50
Worker-Thread 1058
Workspace 76
World Wide Web 56
Wrapper-Klasse 195
write once, run anywhere 65
writeObject(), ObjectOutputStream 821
Writer, Klasse 770
writeReplace() 830
writeUTF(), RandomAccessFile
753
wsimport, Dienstprogramm
1224, 1226
Wurzelelement 875
Wurzelverzeichnis 737
WWW-Authenticate, ResponseHeader 1185
X
X.509 1413
XAML 1065
-Xbootclasspath 514
XDoclet 1340
Xerces 855
XHTML 853
XML 844
XML User Interface Language
1065
XMLDecoder, Klasse 836
XMLEncoder, Klasse 836
XMLEvent, Klasse 857
XMLEventFactory, Klasse 862
XMLEventReader, Klasse 860
XMLEventReader, Schnittstelle
862
XMLEventWriter, Klasse 858
XMLEventWriter, Schnittstelle
863
XMLInputFactory, Klasse 862
XMLOutputFactory, Klasse 862–
863
XMLOutputter, Klasse 873
XMLStreamConstants, Schnittstelle 858
XMLStreamReader, Schnittstelle
857
XMLStreamWriter, Klasse 858
XMLStreamWriter, Schnittstelle
862–863
-Xms 1438
-Xmx 1438
Xnoclassgc 1438
XOPEN SQL-Status 1318
XOR 1070
Xor 119, 168
Xor-Modus, Zeichnen 1105
XPath 884, 887
XPath, Klasse 885
XPath-Wurzel 884
-Xprof 1438
-Xrs 1438
X-Server 1140
XSLT 887
-Xss 1438
XStream 838
XUL 1065
Xvfb-Server 1140
X-Virtual-Framebuffer-Server
1140
Y
YEAR, Calendar 642
yield(), Thread 555
Z
Zahlenwert, Unicode-Zeichen 85
Zeichen 100, 109
Zeichen ersetzen 246
Zeichenbereich 1095
Zeichenkette 96
Zeichenkodierung 278
Zeiger 59
Zeilenkommentar 93
Zeilentrenner 274
Zeilenumbruch 522
Zeitablauf 1208
Zeitgenauigkeit 634
Zeitmessung 525
Zeitverschiebung 633
Zeitzone 624, 632, 651
Zeitzonenabweichung 643
Zertifizierungsstelle 1412
ZipEntry, Klasse 810
ZipFile, Klasse 810
zirkuläre Assoziation 359
ZONE_OFFSET, Calendar 643
Z-Order 1033
Zufallszahl 304, 309
Zufallszahlengenerator 306
Zugriffsmethode 328–329
Zugriffsmodifizierer 1355
zusammengesetzte Bedingung
130
Zustandsänderung 463
Zuweisung 121
Zuweisung mit Operation 121
Zuweisung pro Zeile 112
zweidimensionales Feld 213
Zweierkomplement 291
zweistelliger Operator 110
Zwischenablage 1046
zyklische Redundanzprüfung 817
1477
Herunterladen