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