Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

FAQ der Newsgroup de.comp.lang.java Version 1.44 vom 07.10.2005


[ Usenet FAQs | Web FAQs | Documents | RFC Index | Cities ]
Archive-name: de/comp-lang-java/faq
Posting-Frequency: weekly (Friday)
Last-modified: 2004-10-02
Version: 1.44
URL: ftp://rtfm.mit.edu/pub/usenet-by-group/de.answers/de/comp-lang-java/faq, http://www.faqs.org/faqs/de/comp-lang-java/faq
Expires: 21 Oct 2005 00:00:00 CEST
Tab-Width: 4
Page-Width: 74

See reader questions & answers on this topic! - Help others by sharing your knowledge
  FAQ (Frequently Asked Questions) der Newsgroup de.comp.lang.java v1.44
=========================================================================

Inhalt:
-------

1. Allgemeines

   1.1. Allgemeine Hinweise zum Posten
   1.2. Worum geht es in dieser Newsgroup?
   1.3. Wie kommen h�ufig gestellte Fragen in diese FAQ?
   1.4. Wie kommen die Bugs aus der FAQ?
   1.5. TAGS-Konventionen zu einem einheitlichen Aussehen
   1.6. Ich bekam als Antwort auf meine Frage eine seltsame Buchstaben-
        kombination zugeschickt. Was ist das und wie kann ich es lesen?


2. Was man �ber Java wissen sollte

   2.1. Was ist Java?
   2.2. Verwandtschaft von Java mit anderen Sprachen?
   2.3. WebBrowser und Java
   2.4. Erste Schritte in Java
   2.5. Ich habe das HelloWorld-Programm aus meinem Java-Buch
        abgeschrieben, aber es funktioniert nicht. :-(


3. H�ufig gepostete Fragen

    3.1. [LANG] - Die Sprache Java.
        3.1.1. Gibt es in Java keine Zeiger wie in C++?
        3.1.2. Warum ist Referenz nicht gleich Referenz?
        3.1.3. Wie werden in Java Funktionsparamter �bergeben, by value
               oder by reference?
        3.1.4. Warum gibt es in Java keine Destruktoren wie in C++?
        3.1.5. Warum funktioniert die equals Methode nicht?
        3.1.6. Wenn ich eigene Objekte mit einer Hashtable/HashMap
               verwalte, kommt es zu sonderbaren Effekten. Wieso?
        3.1.7. Was bedeutet das Schl�sselwort final?
        3.1.8. Warum wird der dynamische Parametertyp bei �berladenen
               Funktionen nicht beachtet?
        3.1.9. Was bedeutet super()?
        3.1.10. Was sind anonyme Arrays?
        3.1.11. Gibt es in Java einen Pr�-Prozessor wie in C++?
        3.1.12. Existiert der const Modifizierer von C++ auch in Java?
        3.1.13. Wie kann man Referenzen von �bergabeparametern �ndern?
        3.1.14. Wie erzeuge ich eine  tiefe  Kopie eines Objektes mit
                m�glichst wenig Aufwand?
        3.1.15. Wie kann ich in Java eine dem Programmierer unbekannte
                Anzahl gleichartiger Objekte erzeugen und ihnen passende
                Namen zuweisen, also label1, label2 usw.?
        3.1.16. Wie kann ich den Typ enum aus C++ in Java umsetzen?
        3.1.17. Kann man Mehrfachvererbung mit Java simulieren?
        3.1.18. Wie realisiere ich eine variable Parameterliste?
        3.1.19. Wie realisiere ich eine Methodenauswahl nach den
                dynamischen Parametertypen?
        3.1.20. Sind Methoden in Java immer virtuell?
        3.1.21. Ich stosse ab und zu auf den Begriff "Wrapper-Klassen".
                K�nnte mir jemand erkl�ren was das ist?
        3.1.22. Warum ist private nicht privat?


    3.2. [STRING] - Strings.
        3.2.1. Wie vergleiche ich zwei Strings in Java?
        3.2.2. Wie wandle ich einen String in einen Integer?
        3.2.3. Wie wandle ich einen Integer in einen String um?
        3.2.4. Wie wandle ich einen Integer in einen HexString um?
        3.2.5. Wie kann ich eine Zahl formatieren und wie lege ich die
               Anzahl der Nachkommastellen fest?
        3.2.6. Wie kann ich ein Datum formatieren?
        3.2.7. Wie kann ich in einem String oder StringBuffer mehrere
               Zeichen suchen und ersetzen?
        3.2.8. Gibt es regul�re Ausdr�cke in Java (regular expressions)?


    3.3. [IO] - Eingabe/Ausgabe, Streams, etc.
        3.3.1. Verlangsamt Serialisierung mein Programm?
        3.3.2. Wie kann ich rekursiv einen Verzeichnisbaum abarbeiten?
        3.3.3. Wie kann ich aus Dateien zeilenweise lesen?
        3.3.4. Wie kann ich Exponentialzahlen (z.B. 1.09E+008) aus einer
               Datei lesen?
        3.3.5. Wie kann ich mit Java Dateien kopieren?
        3.3.6. Warum kann ich meine Bilder nicht mehr laden, nachdem ich
               sie in ein Jar gesteckt habe?


    3.4. [NET] - Netzwerk.
        3.4.1. Wie kann ich einen Ping in Java realisieren?


    3.5. [AWT] - Abstract Window Toolkit.
        3.5.1. Wenn ich einen Listener bei mehreren Buttons anmelde, wie
               kann ich dann unterscheiden, welcher gedr�ckt wurde?
        3.5.2. Kann ich ein Fenster (Frame/JFrame) maximieren?
        3.5.3. Wie tausche ich die Kaffeetasse im blauen Balken aus?


    3.6. [SWING] - Swing, das bevorzugte GUI.
        3.6.1. Wie mache ich globale Font-�nderung f�r meine Komponenten?
        3.6.2. Wie kann ich bei der Eingabe in ein JTextField die Anzahl
               der eingebbaren Zeichen beschr�nken?
        3.6.3. Wie setze ich den Cursor an den Anfang der JTextArea?
        3.6.4. Wie scrolle ich an das Ende der JTextArea?
        3.6.5. Wie bekomme ich es hin, das der Benutzer in meiner JTable
               keine Eingaben t�tigen kann?
        3.6.6. Wie bekomme ich eine horizontale ScrollBar bei JTable?
        3.6.7. Wie scrolle ich ans Ende von JTable?
        3.6.8. Wie verhindere ich ein reordering der Spalten bei JTable?
        3.6.9. Wie verhindere ich ein Resizen der Spalten bei JTable?
        3.6.10. Wie �ndere ich die Hintergrundfarbe von JScrollPane?
        3.6.11. Wie kann ich ein JLabel dazu bringen, seinen Hintergrund
                zu f�llen?
        3.6.12. Warum reagiert meine GUI nicht, w�hrend eine l�ngere 
                Berechnung ausgef�hrt wird?


    3.7. [APPLET] - Java-Applets und ihre Zusammenarbeit mit Browsern.
        3.7.1. Welche JDK-Version sollte ich f�r Applets verwenden, die
               m�glichst allgemein lauff�hig sein sollen?
        3.7.2. Wie bekomme ich den Internet Explorer dazu, das Plugin
               anstelle der integrierten JVM zu benutzen.
        3.7.3. Was d�rfen unsignierte Applets nicht aus
               Sicherheitsgr�nden?


    3.8. [SERVER] - Servlets und andere Server-Implementierungen in Java.


    3.9. [NONCORE] - Klassen/Packages, die �ber den Kern der Sprache
                     hinausgehen, also Java3D etc.

    3.10. [OOP] - OOP-Konzepte und Patterns in Java.
        3.10.1. Was bedeutet Vererbung im OO-Kontext?
        3.10.2. Was bedeutet Aggregation im OO-Kontext?
        3.10.3. Was bedeutet Assoziation ist OO-Kontext?
        3.10.4. Was bedeutet Benutzung im OO-Kontext?
        3.10.5. Worin liegen die Unterschiede zwischen abstrakten Klassen
                und Interfaces?
        3.10.6. Was ist eine anonyme innere Klasse?
        3.10.7. Was ist ein immutable Objekt?


    3.11. [JDK] - Virtuelle Maschinen, alles �ber JDKs, deren
                  Installation und Verwendung.
        3.11.1. Was ist ein Java Development Kit (JDK)
        3.11.2. Was ist ein Java Runtime Environment (JRE)
        3.11.3. Was ist eine Java Virtual Machine (JVM)
        3.11.4. Wie konfiguriere ich JDK1.3/1.4 unter Linux oder Unix?
        3.11.5. Wie installiere und konfiguriere ich das jdk unter
                Windows 9x/Me/NT/2000 richtig?


    3.12. [TOOLS] - Java-Zusatz-Tools, zum Beispiel IDEs, Build-Tools,
                    Profiler, etc.
        3.12.1. Welche IDE muss ich verwenden?
        3.12.2. Wie kann man eine Java-Anwendung in eine EXE-Datei
                umwandeln?


    3.13. [MATH] - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.
        3.13.1. Warum rechnet Java falsch?
        3.13.2. Wie runde ich eine Gleitkommazahl?
                Wie formatiere ich eine Gleitkommazahl?
        3.13.3. Wie kann ich in Java Zufallszahlen im Bereich 0..n
                erzeugen?


    3.14. [MISC] - Alles, was nicht in eine der anderen Rubriken pa�t.
        3.14.1. Ich komme mit dem import-Statement nicht klar, was mache
                ich falsch?
        3.14.2. Warum gibt es Probleme bei final Werten in Verbindung mit
                elementaren Typen?
        3.14.3. Was bedeuten "$" im Namen von Class-Files?
        3.14.4. Wie lassen sich Bilder im Dateiformat XYZ laden oder
                speichern?
        3.14.5. Was geht nicht mit Java?
        3.14.6. Wie kann ich in meinem Java-Programm ein HTML-Dokument
                anzeigen lassen?
        3.14.7. Unter Windows werden in der Konsole (DOS-Eingabe-
                 aufforderung) die Umlaute falsch ausgegeben. Wie kann
                 ich das korrigieren?


    3.15. [ERROR] - Fehlermeldungen.
        3.15.1. Warum findet Java den Konstruktor nicht?
        3.15.2. Warum bekomme ich eine "NoClassDefFoundError"
                Fehlermeldung beim Starten von java?
        3.15.3. Warum bekomme ich eine "Couldn't read <Name>"
                Fehlermeldung beim Kompilieren mit javac?
        3.15.4. Warum bekomme ich eine "class <Name> must be defined in
                a file called <Name>" Fehlermeldung  beim Kompilieren
                von javac?
        3.15.5. Warum wird beim Zugriff auf ein korrekt initialisiertes
                Objekt-Array eine NullPointerException geworfen?
        3.15.6. Warum bekomme ich eine NullPointerException, wenn ich
                versuche, auf Methoden oder Attribute von in einem Array
                gespeicherten Objekten zuzugreifen?
        3.15.7. Warum meckert der Compiler bei nicht initialisierten
                final Variablen?
        3.15.8. Was hat die Compilerfehlermeldung "... is deprecated" zu
                bedeuten?


    3.16. [ClassLoader] - Alles �ber Classloader
        3.16.1 Wie funktionieren Classloader?
        3.16.2 Warum macht der Classloader im Servlet-Container Probleme?
               Warum funktioniert das Einlesen von Ressourcen ueber den
               Classloader bei mir nicht?
        3.16.3 Wie lade ich eine Klasse neu?
        3.16.4 Wie baue ich einen Plugin-Mechanismus?
        3.16.5 Gibt's dazu auch Beispielcode?
        3.16.6 ClassLoader Ressourcen zu 3.16.1 bis 3.16.5


4. B�cher zum Thema Java

    4.1. Kann mir jemand gute Literatur zum Thema Java empfehlen?


5. Themenverwandte Internet Ressourcen

    5.1 WWW-Sites
    5.2 Newsgroups
    5.3 Mailinglisten


6. JavaScript Internet Ressourcen.

    6.1 WWW-Sites
    6.2 Newsgroups


7. Credits
_____________________________________________________________________

1. Allgemeines
==============

1.1. Allgemeine Hinweise zum Posten
-----------------------------------
Wenn du neu im Usenet bist, solltest du auf jeden Fall die Texte in
der Newsgroup <news:de.newusers.infos> lesen. Du findest sie auch im
WWW auf <URL:http://www.kirchwitz.de/~amk/dni/>. In diesen Texten
erh�lt man einen �berblick �ber die im Usenet �blichen Regeln
("Netiquette"). Auf diese Weise lassen sich die meisten Anf�nger-
fehler verhindern und man vermeidet, gleich f�r sein erstes Posting
wegen formaler Fehler angeschnauzt zu werden. Falls du Fragen zu den
Regeln im Usenet hast, stelle sie bitte in der Newsgroup
<news:de.newusers.questions>.

Weitere Links zum Thema:

    <URL:ftp://rtfm.mit.edu/pub/usenet/de.answers/de-newusers/>
    <URL:http://learn.to/quote/>


1.2. Worum geht es in dieser Newsgroup?
     Autor: Markus Reitz
---------------------------------------
In der Newsgroup <news:de.comp.lang.java> sollen Probleme und L�sungen,
die sich im Zusammenhang mit der Programmiersprache Java ergeben,
diskutiert werden. Die Newsgroup besch�ftigt sich nur mit der Sprache
Java! JavaScript oder herstellerspezifische Implementierungen (z.B.
Microsoft J++) besitzen eigene Newsgroups, in denen diese
spezifischen Probleme und L�sungen diskutiert werden. Neben der
Newsgroup <news:de.comp.lang.java> gibt es noch weitere (vor allem
englischsprachige) Newsgroups, die sich mit der Programmiersprache
Java besch�ftigen. Siehe auch den Abschnitt "Themenverwandte
Newsgroups".

1.3. Wie kommen h�ufig gestellte Fragen in diese FAQ?
     Autor: Uwe G�nther
-----------------------------------------------------
Nachdem man festgestellt hat, dass man in einem bestimmten Zyklus die
gleiche Frage immer wieder mit der gleichen Antwort beantworten muss -
nur weil die Unis ihren Lehrplan mal wieder ge�ndert haben, in der c't
mal wieder ein "Wie programmiere ich ein Applet"-Kurs unter die Leute
gebracht wurde oder aus welchen Gr�nden auch immer - sollte man einen
neuen Thread mit dem

    Subject: [FAQ] Neue Frage: <Frage>

beginnen.

Der Body dieser Nachricht sollte folgendes Format besitzen:

--Schnipp--
Frage: <Frage>

Antwort: <Antwort>

Beispiel: <Code>
--Schnapp--

Wobei der Text in spitzen Klammern, dein Part ist. Die Zeilenl�nge darf
74 Zeichen nicht �berschreiten. Der Code sollte die Code Conventions von
Sun einhalten - wenn du nicht weisst was das ist, solltest du besser
keine FAQ schreiben. Der gesamte Text darf keine Tabs enthalten und bei
Bedarf gegen 4 Leerzeichen ersetzt werden. Es ist von grossem Vorteil
wenn der Beispiel-Code kompilierbar ist. Das steigert die Qualit�t der
FAQ ungemein.

Nachdem der Thread dann von den Regulars und den anderen Lesern von
de.comp.lang.java geb�hrend behandelt wurde und etwaige Probleme
ausger�umt wurden, muss die Endfassung des Textes an die im Header dieser
FAQ angegebene e-mail Adresse des FAQ-Maintainers von de.comp.lang.java
gesendet werden. Dabei ist es erw�nscht die Rubrik, oder gleich die
zuk�nftige Fragennummerierung mit anzugeben. Weiterhin muss die
Message-ID mit angegeben werden, damit der FAQ-Maintainer �berpr�fen kann
ob er nicht von irgendjemanden vereimert wird. ;-)


1.4. Wie kommen die Bugs aus der FAQ?
     Autor: Uwe G�nther
-------------------------------------
Nachdem man festgestellt hat, dass die FAQ einen Fehler hat, kann man
diesen dem FAQ-Maintainer unter Angabe eines Workarounds direkt
mitteilen.


1.5. TAGS-Konventionen zu einem einheitlichen Aussehen
     Autor: Markus Reitz
--------------------------------------------------------
Neben den schon weiter oben genannten Ratschl�gen, die allgemeine
Anmerkungen zum Posten in Newsgroups darstellen, folgen nun einige
spezifische Anmerkungen zur Schreibweise des Subjects in der
Newsgroup <news:de.comp.lang.java>. Vor einiger Zeit wurde die
Einf�hrung sogenannter Tags vorgeschlagen, die die �bersichtlichkeit
steigern sollen. Hintergrund ist die einfache Idee, den Inhalt des
Postings durch ein eindeutiges Schl�sselwort, das Tag, zu
charakterisieren. Mit einem entsprechend konfigurierten Newsreader ist
es dann m�glich, sich solche Nachrichten hervorheben zu lassen, wodurch
man direkt auf einen Blick Postings beispielsweise zum Thema Swing
�berschauen kann. Tags werden an den Anfang des Subjects, in eckigen
Klammern eingeschlossen, geschrieben. Damit Einheitlichkeit gewahrt
wird, sollten die folgenden Tags verwendet werden. Wenn jeder seine
eigenen Tags spezifizieren w�rde, w�re die Einheitlichkeit verloren und
es w�rde genau-soviel Chaos wie vorher herrschen. Deshalb an dieser
Stelle die Bitte, sich an die Vorgaben zu halten. Bei
�nderungsvorschl�gen bitte in die Newsgroup zur Diskussion posten und
bei Akzeptanz in der Newsgroup werden die Vorschl�ge an dieser Stelle
in die FAQ aufgenommen.

Liste der Tags in <news:de.comp.lang.java>:

Tags f�r Fragen:

    [LANG]
    - Frage bez�glich der Sprache Java.

    [STRING]
    - Fragen die unmittelbar mit Strings zu tun haben.

    [IO]
    - Frage bez�glich Eingabe/Ausgabe, Streams, etc. in Java.

    [NET]
    - Frage bez�glich Netzwerk.

    [AWT]
    - Frage bez�glich AWT.

    [SWING]
    - Frage bez�glich Swing.

    [APPLET]
    - Frage zu Java-Applets und ihre Zusammenarbeit mit Browsern.

    [SERVER]
    - Frage zu Servlets und anderen Server-Implementierungen in Java.

    [NONCORE]
    - Fragen zu Klassen/Packages, die �ber den Kern der Sprache
      hinausgehen, also Java3D etc.

    [OOP]
    - Frage bez�glich OOP-Konzepten und Patterns in Java.

    [JDK]
    - Frage zu virtuelle Maschinen, alles �ber JDKs und deren
      Installation und Verwendung.

    [TOOLS]
    - Frage zu einem Java-Zusatz-Tool, zum Beispiel IDEs, Build-Tools,
      Profiler, etc.

    [MATH]
    - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.

    [MISC]
    - Alles, was nicht in eine der anderen Rubriken pa�t.

    [ERROR]
    - Fragen zu Fehlermeldungen.

    [OT]
    - Alles was hochgrading off-topic ist und nicht direct mit Java zu
      tun hat. ;-)


Tags "nicht"-Fragen:

    [INFO]
    - Allgemeine Informationen, z.B. Links auf Webseiten

    [DISCUSSION]
    - Diskussion zu einem Java-spezifischen Thema

    [ANNOUNCE]
    - Vorstellung neuer Software

    [PROST]
    - Darf nur von Regulars verwendet werden, die wissen was sie tun. ;-)


1.6. Ich bekam als Antwort auf meine Frage eine seltsame Buchstaben-
     kombination zugeschickt. Was ist das und wie kann ich es lesen?
     Autor: Stephan Menzel
--------------------------------------------------------------------
Diese Kombination ist eine sogenannte Message-ID und bezeichnet einen
Usenetartikel eindeutig.

Vorgehensweise bei Message-ID-Angaben:

(a) man hat einen Newsreader, der damit umgehen kann:
    - einfach draufklicken.

(b) Wenn man Opera ab Version 6 verwendet, kann man in der Adressleiste
einfach "r msgid:a2kpac.14g.1@aljoscha-rittner.de" eingeben und gelangt
zur entsprechenden Seite von Google Groups.

(c) ansonsten: http://groups.google.com,
dann msgid:a2kpac.14g.1@aljoscha-rittner.de eingeben.

(d) Wenn man gerne URLs bastelt:
http://groups.google.com/groups?q=msgid:a2kpac.14g.1@aljoscha-rittner.de

(e) oder http://groups.google.com/advanced_group_search dann Msg-ID bei
"Beitrags-ID" eingeben.



2. Was man �ber Java wissen sollte
==================================

2.1. Was ist Java
     Autor: Markus Reitz
------------------------
Zuersteinmal: Java ist nicht JavaScript. JavaScript ist eine Sprache,
die federf�hrend von der Firma Netscape entwickelt wurde, um die
Inhalte von Webseiten dynamischer und interaktiver zu gestalten.
JavaScript-Programme werden in den HTML-Quelltext der Seite
eingebettet und vom Browser interpretiert und ausgef�hrt. Zwar macht
JavaScript viele Anleihen bei Java, ist aber bei weitem nicht so
flexibel.

    Die deutsche Newsgroup zu JavaScript findet man unter:

        <news:de.comp.lang.javascript>

    Die Website von de.comp.lang.javascript ist unter folgendem
    Link zu finden:

        <URL:http://www.dcljs.de/>

Java wurde von der Firma SUN Microsystems mit dem Ziel entwickelt, eine
moderne, objektorientierte Sprache zu schaffen. Durch das Ziel der
Plattformunabh�ngigkeit ist Java vor allem im Zusammenhang mit der
Entwicklung von Web-Applikationen im Internet eine der am h�ufigsten
verwendeten Sprachen. Doch Java beschr�nkt sich nicht nur auf das
Erstellen von Effekten f�r die Webseite, Java ist eine ausgewachsene
Programmiersprache, mit der man alle anstehenden Probleme l�sen kann.
Die Syntax der Sprache ist an die von C++ angelehnt, Schl�sselw�rter
sind ver�ndert bzw. in der Bedeutung erweitert worden, bestimmte
Features von C++ wurden zugunsten der �bersichtlichkeit bzw. Sicherheit
nicht in Java verwendet. Java Programme liegen im sogenannten Bytecode
vor, der Maschinencode f�r einen fiktiven Prozessor, der von der VM, der
virtuellen Maschine, ausgef�hrt wird. Durch die Verwendung des Bytecodes
wird die Plattformunabh�ngigkeit von Java garantiert - dieser Vorteil
wird aber durch die, im Vergleich zu anderen Sprachen wie C++, wesentlich
langsamere Ausf�hrungsgeschwindigkeit bezahlt.


2.2. Verwandtschaft von Java mit anderen Sprachen?
     Autor: Markus Reitz
-------------------------------------------------
Java bietet eine Reihe von neuen Features, orientiert sich aber auch
an etablierten Sprachen wie C++, Smalltalk oder Objective-C.
Prinzipien aus diesen Sprachen wurden �bernommen und teilweise
erweitert. Die folgende Tabelle gibt einen kleinen �berblick �ber
Features von Java, die aus anderen Sprachen quasi "entliehen" wurden.

                                 |-----|-----------|-------------|
                                 | C++ | Smalltalk | Objective-C |
|--------------------------------|-----|-----------|-------------|
| Primitive Datentypen           |  *  |           |             |
|--------------------------------|-----|-----------|-------------|
| Universelle Basisklasse Object |     |     *     |             |
|--------------------------------|-----|-----------|-------------|
| Garbage Collection             |     |     *     |             |
|--------------------------------|-----|-----------|-------------|
| Konstruktoren                  |  *  |           |             |
|--------------------------------|-----|-----------|-------------|
| Statische Typen                |  *  |           |             |
|--------------------------------|-----|-----------|-------------|
| Bibliothek von Standardklassen |     |     *     |             |
|--------------------------------|-----|-----------|-------------|
| Interfaces                     |     |           |      *      |
|--------------------------------|-----|-----------|-------------|

Im Vergleich zu C++ besitzt Java folgende Unterschiede:

  - noch keine Templates
  - keine Operatoren�berladung
  - kein prozeduraler Overhead
  - keine Mehrfachvererbung von Klassen


2.3. WebBrowser und Java
     Autor: Markus Reitz
------------------------
Java z�hlt immer noch zu den  j�ngeren  Programmiersprachen und die
Entwicklung verl�uft in manchen Bereichen noch mit hoher
Geschwindigkeit. Insbesondere Zusatz-APIs findet man inzwischen wie
Sand am Meer und praktisch jede neue Version des JDK bietet
Verbesserungen oder Erweiterungen der bestehenden APIs.

Dies wird insbesondere dann problematisch, wenn man Java-Applets
schreiben m�chte, die in den bekannten Web-Browsern von Netscape oder
Microsoft laufen sollen. H�ufig werden aktuelle Features nur
unzureichend oder gar nicht unterst�tzt. Deshalb sollte man folgendes
beachten:

  - �ltere Webbrowser unterst�tzen (im g�nstigsten Fall) nur die
    Version 1.0 der Sprache
  - Neuere Webbrowser unterst�tzen zumindest teilweise die
    Sprachversion 1.1 (Netscape ab Version 4.04-J2, Microsoft
    Internet-Explorer ab Version 4.0)

Um eine m�glichst gro�e Anzahl an Plattformen bedienen zu k�nnen, mu�
man sich also am besten auf Features der Sprache beschr�nken, die schon
in der UrVersion vorhanden waren. Bei neueren Features l�uft man
Gefahr, da� Besitzer �lterer Browser ausgeschlossen werden. Eine andere
Alternative bietet die Verwendung des von SUN erh�ltlichen
Java-Plug-In's. Dadurch werden �ltere Browserversionen mit den Features
der aktuellen Java-Version aufger�stet, wodurch es dann sogar m�glich
wird, Java 2 - Programme in Browsern ablaufen zu lassen, obwohl diese
die neueste Version urspr�nglich noch gar nicht unterst�tzen. Das
Plug-In ist auf der Homepage von SUN erh�ltlich, problematisch ist
allerdings die Gr��e. Es ist daher fraglich, ob Benutzer bereit sind,
sich wegen eines kleinen Homepage-Effektes ein gro�es Plug-In
herunterzuladen. Sinn macht das Plug-In daher nur bei wirklich gr��eren
Programmen oder bei Programmen, die f�r den Einsatz im Intranet
ausgerichtet sind.


2.4. Erste Schritte in Java
     Autor: Markus Reitz
---------------------------
Erfahrungen mit der Sprache Java zu sammeln ist nicht schwer. Sofern
man einen Internetzugang hat, kann man sich die Sprachdefinition,
Compiler etc. direkt von SUN besorgen. Es empfiehlt sich die Verwendung
der Java-Implementierung von SUN, denn diese ist die Referenz f�r alle
anderen Implementierungen und normalerweise die, die sich am aktuellsten
Sprachstandard orientiert. L�sungen von Microsoft oder Symantec haben
den Nachteil, da� Features modifiziert oder gar nicht implementiert
werden oder F�higkeiten hinzukommen, die der urspr�nglichen
Sprachimplementation fehlen. Au�erdem bietet das JDK (Java Development
Kit) von SUN den Vorteil, da� es kostenlos verf�gbar ist. Nachteil:
Compiler und Tools arbeiten kommandozeilenorientiert, d.h. man schreibt
den Quellcode mit einem beliebigen Editor, speichert die Datei und f�hrt
dann den Compiler aus. Bei Fehlern l�dt man die Datei, korrigiert den
Fehler und das ganze Spiel beginnt von vorne. Abhilfe schaffen IDEs
(Integrated Development Environment), die das JDK steuern und Fehler
und andere Meldungen direkt anzeigen, ohne da� der Quelltexteditor
verlassen werden mu�. Ein weiterer Vorteil von IDEs ist das Feature
Syntax Highlighting, das die Schl�sselw�rter der Sprache farblich
hervorhebt und dadurch die �bersichtlichkeit steigert.

Bezugsquelle f�r das JDK: <URL:http://www.java.sun.com/j2se/>


2.5. Ich habe das HelloWorld-Programm aus meinem Java-Buch
     abgeschrieben, aber es funktioniert nicht. :-(
     Autor: Hubert Partl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Newbie:
Ich habe das HelloWorld-Programm aus meinem Java-Buch abgeschrieben,
aber es funktioniert nicht. :-(

Oldie:
Das ist schon richtig :-) so, das HelloWorld-Beispiel dient dazu,
dass Du die typischen Anfaenger-Fehler kennenlernst und in Zukunft
vermeiden kannst.

In diesem Fall kann ich nur raten: Du hast wahrscheinlich einen der
folgenden typischen Newbie-Fehler gemacht:

* Du hast das Programm nicht genau genug abgeschrieben (Tippfehler,
Gross-Kleinschreibung, Sonderzeichen, Leerstellen), lies doch die
Fehlermeldungen und Korrekturhinweise, die der Compiler Dir gibt.


* Du hast das Programm nicht unter dem richtigen Filenamen abgespeichert.
Wenn die Klasse HelloWorld heisst, muss das File HelloWorld.java heissen,
nicht helloworld.java und auch nicht HelloWorld.java.txt, im letzteren
Fall versuch es mit

    notepad "HelloWorld.java"


* Du hast beim Compiler nicht den kompletten Filenamen mit der Extension
angegeben (wieder mit der richtigen Gross-Kleinschreibung):

   javac HelloWorld.java


* Du hast bei der Ausfuehrung nicht den Klassennamen ohne die Extension
angegeben (wieder mit der richtigen Gross-Kleinschreibung):

    java HelloWorld


* In der Umgebungsvariable PATH ist das Directory, in dem sich die
JDK-Software befindet, nicht neben den anderen Software-Directories
enthalten, versuch

    set PATH=%PATH%;C:\jdk1.2\bin

oder wie immer das auf Deinem Rechner heissen muss.


* Die Umgebungsvariable CLASSPATH ist (auf einen falschen Wert) gesetzt.
Diese Variable sollte ueberhaupt nicht gesetzt sein, nur in seltenen
Spezialfaellen und dann so, dass sie sowohl die Stellen enthaelt,
wo die Java-Klassenbibliotheken liegen, als auch den Punkt fuer das
jeweils aktuelle Directory.


* Du hast den Compiler nicht in dem Directory bzw. Folder aufgerufen,
in dem Du das Java-File gespeichert hast.


* Du hast ein Applet als Applikation aufgerufen, oder umgekehrt.
Applikatonen, die eine main-Methode enthalten, musst Du mit

    java Classname

aufrufen. Applets, die ein "extends Applet" oder "extends JApplet"
enthalten, musst Du innerhalb eines geeigneten HTML-Files mit

    appletviewer xxxxx.html

oder mit Netscape oder Internet-Explorer aufrufen.


Mehr darueber findest Du in meiner Java-Einfuehrung auf

    <URL:http://www.boku.ac.at/javaeinf/jein1.html#software>


Aehnliche Hinweise findest Du im Java Glossary von Roedy Green auf

    <URL:http://mindprod.com/gloss.html>



3. H�ufig gepostete Fragen
==========================


3.1. [LANG] - Frage bez�glich der Sprache Java.
-----------------------------------------------

3.1.1. Gibt es in Java keine Zeiger wie in C++?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Im Prinzip gibt es ein Konstrukt, das den Zeigern anderer
Programmiersprachen, wie zum Beispiel C++, sehr �hnlich ist: die
sogenannten Referenzen. Referenzen k�nnen, im Vergleich zu Zeigern in
C++, nicht manipuliert werden; die sogenannte Zeigerarithmetik, bei der
man Zeiger auf beliebige Speicherinhalte zeigen lassen kann, wurde aus
Sicherheitsgr�nden nicht in Java �bernommen. Der Inhalt einer Referenz
kann einer anderen Referenz zugewiesen werden, Referenzen k�nnen
miteinander verglichen werden. Wird in Java eine Objektvariable
angelegt, so ist dies nichts weiter als ein Speicherplatz f�r eine
Referenz f�r ein Objekt des angegebenen Typs. Der new-Operator erzeugt
das eigentliche Objekt und liefert die Referenz darauf zur�ck, die dann
in der Objektvariablen gespeichert wird.


3.1.2. Warum ist Referenz nicht gleich Referenz?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Problem:

public class Test {
    public static void main (String[] args) {
        String a = "A";
        String x = a;
        System.out.println(x);
        a = "B";
        System.out.println(x);
    }
}

Die Ausgabe sollte doch eigentlich so aussehen:

    A
    B

Denn die Variable x speichert doch eine Referenz auf den String a! Im
ersten Fall hat a den Wert  A  und damit auch x, das ja auf diesen
String verweist. Im zweiten Fall wird a ge�ndert und damit m��te sich
doch auch eigentlich der Wert von x �ndern, weil x auf a verweist.
Die Ausgabe, die das Programm liefert, ist jedoch:

    A
    A

was eigentlich nicht in das Bild einer normalen Referenz passt.


Ursache:

Der Fehler liegt darin begr�ndet, da� a nicht der eigentliche String
ist, sondern nur eine Referenz auf diesen String. Durch x = a
referenzieren beide Variablen den selben String und durch a = "B"
verweist a auf einen anderen neuen String mit dem Wert B. Dies �ndert
jedoch nichts an der Referenz, die in x gespeichert ist. Somit ist die
Ausgabe v�llig korrekt.



3.1.3. Wie werden in Java Funktionsparamter �bergeben, by value
       oder by reference?
       Autor: Paul Ebermann
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java kennt  (genauso wie C, aber im Gegensatz zu etwa Pascal) kein
"Call by Reference". Wenn Objekte als Parameter verwendet werden, wird
eben die Referenz "by Value" �bergeben. Somit kann man zwar das Objekt
(so es ver�nderbar ist) ver�ndern, aber nicht die originale Variable,
die als Parameter verwendet wurde.

Beispiel f�r Call by Reference:
(Pascal - [Syntax bestimmt nicht korrekt])

program ReferenzTest(input, output);

  var
  x, y : integer;

  procedure swap (var a: integer; var b: integer);
    var
    h : Integer;

  begin
    h := a;
    a := b;
    b := h;
  end;

begin
  x := 1;
  y := 2;
  swap(x,y);
  writeLn('x = ', x, ', y = ', y , '.');
end.

Das Programm gibt am Ende x = 2 und y = 1 aus.
In Java geht das nicht:

package de.dclj.faq;
class CallByReferenceTest
{
    static void swap (int a, int b)
    {
        int h = a;
        a = b;
        b = h;
    }

    public static void main(String[] test)
    {
        int x = 1;
        int y = 2;
        swap(x,y);
        System.out.println("x = " + x + ", y = " + y);
    }
}

Zur Call-by-Reference-Simulation bietet sich
die Verwendung von Arrays an - da diese Objekte sind,
wird ja nur die Referenz �bergeben.


class CallByReferenceSimulation
{
    static void swap(int[] a, int[] b)
    {
        int h = a[0];
        a[0] = b[0];
        b[0] = h;
    }

    public static void main(String[] test)
    {
        int[] x = {1};
        int[] y = {2};
        swap(x,y);
        System.out.println("x = " + x[0] + ", y = " + y[0]);
    }
}

Einen etwas anderen Blickwinkel zu diesem Thema bietet die Webseite:

<URL:
http://purl.net/stefan_ram/pub/java_referenzvariablen_als_argument_de>


3.1.4. Warum gibt es in Java keine Destruktoren wie in C++?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In Java hat der Programmierer unter normalen Umst�nden keinen direkten
Einflu� darauf, wann Objekte aus dem Speicher entfernt werden. So ist
es unter anderem nicht m�glich, ein Objekt per Befehl aus dem Speicher
zu l�schen. Dies erledigt der sogenannte Garbage-Collector, der Objekte
aus dem Speicher entfernt, auf die keine Referenz mehr verweist.
Dadurch wird verhindert, da� der Programmierer mehr oder minder
mutwillig Speicherfehler erzeugen kann, die das Programm zum Absturz
bringen k�nnten. Wann die Entfernung aus dem Speicher erfolgt, liegt im
Ermessen des Computers. Es gibt also keinen definierten Zeitpunkt, wann
ein Objekt nicht mehr existiert und deshalb ist es in den meisten F�llen
nicht sinnvoll, Operationen zu definieren, die beim L�schen des
Objektes ausgef�hrt werden. Man k�nnte (ung�ltige) Annahmen voraussetzen
- zum Beispiel bei verketteten Listen, da� das Nachfolgerelement noch
existiert, obwohl dies gar nicht der Fall ist - und damit Fehler
verursachen. Destruktoren wie in C++ existieren deshalb nicht. Ist es
aus irgendeinem dringenden Grund dennoch n�tig, Operationen beim L�schen
des Objektes auszuf�hren, so kann man eine Methode finalize definieren,
die bei der Speicherbereinigung abgearbeitet wird. Wobei nicht garantiert
wird die finalize methode �berhaupt von der JVM abgearbeitet wird.


3.1.5. Warum funktioniert die equals Methode nicht?
       Autor: Markus Reitz
       Autor: Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem 1:

Man hat eine eigene Klasse entworfen und m�chte nun testen, ob zwei
Objekte gleich sind. Fein, denkt man sich, daf�r bietet die Klasse
Object ja die Methode equals(Object obj). Doch das Programm mit
Verwendung der equals(Object obj) Methode wird zwar korrekt �bersetzt,
der Vergleich funktioniert jedoch nicht so, wie er eigentlich sollte.

Per Default sagt equals(), dass es sich um die selbe Instanz einer
Klasse handelt:

public class Object {
    ...

    public boolean equals(Object other) {
        return this == other;
    }

    ...
}

L�sung 1:

Die Methode equals(Object obj) mu� f�r jede Klasse neu �berschrieben
werden. Schlie�lich kann man nicht in allgemeiner Weise die Gleichheit
zweier Objekte einer Klasse spezifizieren. Das ist insbesondere dann
wichtig falls die Objekte in einer Set oder als Keys f�r eine Map
verwendet werden. Dann muss allerdings auch die Methode hashCode()
�berschrieben werden.  Siehe dazu auch die n�chste Frage in dieser FAQ!

Dazu sollte man sich auf alle F�lle in der JavaDoc zu Object, speziell
die Methoden hashCode() und equals(Object obj) ansehen:

    <URL:http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html>

F�r Strings beispielsweise sind equals() und hashCode() bereits
�berschrieben. So dass String-Objekte als Keys verwandt werden k�nnen.


Problem 2:

public class Test {

    private int a;
    private int b;

    public Test (int a , int b) {
        this.a = a;
        this.b = b;
    }

    public boolean equals(Test other) {
        return (this.a == other.a) && (this.b == other.b);
    }
}

Verwendet man nun Objekte dieser Klasse in Containerklassen und hier
insbesondere Methoden, die auf die Methode equals des Objekts
zur�ckgreifen, so funktioniert dies nicht. Der Grund liegt in der
falschen Signatur der Methode equals. Der Parameter mu� vom Typ Object
sein und nicht vom Typ der Klasse, zu dem die Methode geh�rt. Ansonsten
existieren f�r die Klasse Test zwei Versionen der equals Methode: Eine,
die von der Klasse Object geerbt wurde und die als Parametertyp auch
Object besitzt und als zweite die oben definierte. Containerklassen
verwenden aber die erste und da diese nicht ver�ndert wurde, wird nicht
das gew�nschte Ergebnis erzielt.

L�sung 2:

public class Test {

    private int a;
    private int b;

    public void Test (int a , int b) {
        this.a = a;
        this.b = b;
    }

    //Die hash-Funktion ist aus dem Buch "Effective Java" von
    //Joshua Bloch.
    public int hashCode() {
        int result = 17;
        result = 37*result + this.a;
        result = 37*result + this.b;
        return result;
    }

    public boolean equals(Object obj) {
        //F�r eine bessere Performance.
        if (this == obj) {
            return true;
        }
        //Wenn (obj == null) dann gibt instanceof false zur�ck
        //Siehe JLS 15.20.2
        if (!(obj instanceof Test)) {
            return false;
        }
        Test other = (Test)obj;
        return (this.a == other.a) && (this.b == other.b);
    }
}


3.1.6. Wenn ich eigene Objekte mit einer Hashtable/HashMap verwalte,
       kommt es zu sonderbaren Effekten. Wieso?
       Autor: Ingo R. Homann, Gerhard Bloch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Damit eigene Objekte als Schluessel in einer Hashtable/HashMap
funktionieren, muessen zwei Bedingungen erfuellt sein:

1. Wenn man die equals-Methode einer Klasse �berschreibt, sollte man
   beachten, dass man auch die hashCode-Methode �berschreiben mu�!
2. Nichts, was equals-Vergleiche beeinflusst, darf geaendert werden,
   waehrend das Objekt in einer Hashtable/HashMap ist! Insbesondere darf
   sich der Hashcode nicht aendern.

Man muss sicherstellen, dass Objekte, die laut der equals-Methode gleich
sind, auch einen identischen Hashcode haben m�ssen. Der Umkehr-Schluss,
dass ungleiche Objekte (bei denen equals false liefert) zwangsl�ufig
auch unterschiedliche Hashcodes haben m��en, gilt nicht. Trotzdem sollte
man als Programmierer versuchen, m�glichst darauf hinzuarbeiten (und
keineswegs z.B. f�r alle Objekte einen gleichen, konstanten Hashcode
liefern!), damit die Implementierungen von Hashtable und HashMap
effizient arbeiten k�nnen.

Als Folge dieser Forderung sollten zur Berechnung des Hashcode genau die
Attributwerte einbezogen werden, die auch zur equals-Bestimmung
verwendet werden, insbesondere aber keine anderen Werte!

Die Forderung kann auch so formuliert werden:
        a.equals(b) => (a.hashCode() == b.hashCode())
oder    (a.hashCode() != b.hashCode()) => !a.equals(b)


Eine Hashtable funktioniert vereinfacht folgendermassen:
Die Schluessel-Wert-Paare werden beim Einfuegen in Buckets ("Eimer")
verteilt. Dabei entscheidet der Hashcode des Schluessels, in welchen
Bucket er kommt.
Beim Suchen wird anhand des Hashcodes des Suchschluessels der Bucket
ermittelt, in dem das gesuchte Objekt liegen muss. So k�nnen (au�er
in ung�nstigen F�llen) fast alle Schluessel der Tabelle ausgeschlossen
werden, der Suchschluessel muss nur noch innerhalb des Buckets gesucht
werden; falls er (genauer: ein Schluessel, dessen equals-Vergleich mit
dem Suchschluessel true ergibt) dort gefunden wird , wird der Wert
zurueckgegeben.
Dies funktioniert deshalb, weil aufgrund der obigen Forderung nur
diejenigen Objekte uebereinstimmen koennen, die auch im Hashcode
uebereinstimmen (equals => gleicher Hashcode).

Ein Problem ergibt sich, wenn nach dem Einfuegen ein Schluessel
geaendert wird. Da sich dadurch auch dessen Hashcode (mit ziemlicher
Sicherheit) aendert, liegt er nun im falschen Bucket. Die Hashtable
bekommt von der Aenderung ja nichts mit!
Deshalb ist zu beachten, dass sich Schluessel nicht aendern, solange sie
in einer Hashtable verwendet werden. Sichergestellt werden kann dies nur
durch immutalbe Objekte (siehe 3.10.7).

Beispiel fuer das richtige Ueberschreiben von hashCode:

public class Name {
    private static int zaehler= 0;

    private String     vorname
    private String     nachname;
    private final int  id = zaehler++;

    public Name(String vorname, String nachname) {
        this.vorname = vorname;
        this.nachname = nachname;
    }

    public boolean equals(Object o) {
        // die id ist nur fuer interne Zwecke und hat keinen Einfluss
        // auf Gleichheit
        if(o instanceof Name) {
            Name n = (Name)o;
            return vorname.equals(n.vorname) &&
                   nachname.equals(n.nachname);
        } else {
            return false;
        }
    }

    public int hashCode() {
        // Es werden genau die Werte einbezogen, die auch in der
        // equals-Methode verwendet werden
        int result = 17;
        result = 37*result + vorname.hashCode();
        result = 37*result + nachname.hashCode();
        return result;
    }
}


3.1.7. Was bedeutet das Schl�sselwort final?
       Orginalautor: Markus Reitz
       Autor: Paul Ebermann
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Klassen oder Methoden, die das Schl�sselwort final tragen, k�nnen nicht
mehr �berschrieben werden, wenn von dieser Klasse abgeleitet wird. Die
Verwendung dieses Schl�sselwortes bietet sich aus zwei Gr�nden an:

  - Realisierung von Sicherheitsma�nahmen
  - Codeoptimierung

Sicherheitsma�nahmen werden realisiert, weil es nicht m�glich ist, die
Bedeutung der Methode in abgeleiteten Klassen zu ver�ndern und damit
bestehende Konzepte zu durchbrechen. Codeoptimierung deshalb, weil der
Compiler nun davon ausgehen kann, da� sich an den Methoden nichts mehr
�ndern wird und deshalb elegantere Codeoptimierungen m�glich sind. In
Anbetracht der Tatsache, da� final-Methoden nicht mehr ver�ndert werden
k�nnen, mu� man sich beim Programmentwurf sehr sicher sein, da� das
Feature des �berschreibens definitiv nicht f�r diese Methode ben�tigt
wird, ansonsten kann es bei Verbesserungen des Codes zu Problemen
kommen.

Wenn Variablen mit dem Schl�sselwort final deklariert werden, hat das
zur Folge, dass ihr Wert nur einmal zugewiesen (initialisiert) und dann
nicht mehr ver�ndert werden kann. Wenn der Compiler das nicht nachweisen
kann, gibt es einen Fehler.

* Bei Exemplarvariablen kann die Zuweisung direkt in der Deklaration, in
einem Initialisierungsblock oder in (dann allen) Konstruktoren erfolgen.
Bei Klassenvariablen kann die Zuweisung direkt in der Deklaration oder
in einem Klassen-Initialisierungsblock erfolgen.

* Bei lokalen Variablen muss die Zuweisung in der Deklaration oder
irgendwo sp�ter im Code, jedenfalls vor dem ersten Lese-Zugriff erfolgen.

* Bei Methoden- oder Konstruktor-Parametern mit final kann keine
Zuweisung erfolgen.


3.1.8. Warum wird der dynamische Parametertyp bei �berladenen
       Funktionen nicht beachtet?
       Autor: Uwe G�nther, Erwin Hoffmann, Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dies ist ein korrektes Verhalten gem�� der Java-Sprachspezifikation!

Die Entscheidung, welche �berladene Methode bei der �bergabe eines
bestimmten Parameters auszuw�hlen ist, wird nicht anhand des Typs des
an die Methode �bergebenen Objekts getroffen, sondern anhand des Typs
der Referenz, die auf das �bergebene Objekt verweist.
Diese Entscheidung wird vom Compiler getroffen. Hier muss also zur
Compilezeit entschieden werden, welche Methode aufgerufen werden soll.
Der Compiler kann sich nur auf den Referenztyp beziehen, weil der
Objekttyp nur dynamisch zur Laufzeit eines Programms festgestellt werden
kann.

Das Ganze demonstriert ein Beispielprogramm:

public class BasisKlasse {}

public class AbgeleiteteKlasse extends BasisKlasse {}

public class Test {
    public static void methode(BasisKlasse eineKlasse) {
        System.out.println("Methode mit BasisKlasse!");
    }

    public static void methode(AbgeleiteteKlasse eineKlasse) {
        System.out.println("Methode mit AbgeleiteteKlasse!");
    }

    public static void testMethode(BasisKlasse a) {
        if (a instanceof AbgeleiteteKlasse) {
            System.out.print("Abgeleitet: ");
        } else {
            System.out.print("Basis: ");
        }

        //Welche Methode wird jetzt gerufen?
        methode(a);
    }

    public static void main (String[] params) {
        BasisKlasse a = new BasisKlasse();
        AbgeleiteteKlasse b = new AbgeleiteteKlasse();
        testMethode(a);
        testMethode(b);
    }
}

Das Programm erzeugt folgende Ausgabe:

    Basis: Methode mit BasisKlasse!
    Abgeleitet: Methode mit BasisKlasse!


3.1.9. Was bedeutet super()?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Werden Ableitungen von Klassen gebildet und dabei Funktionen redefiniert
(�berschrieben), so ist es in vielen F�llen n�tig, auf die
Funktionalit�t der Basisklasse zur�ckzugreifen. Mit super.methode()
teilt man mit, da� man die Methode der Basisklasse und nicht die
Methode der aktuellen Klasse benutzen will. Innerhalb eines
Konstruktors ist es m�glich mit super() den Konstruktor der Basisklasse
aufzurufen. Findet im Konstruktor kein expliziter Aufruf mit super()
statt, so wird automatisch der parameterlose Konstruktor
(Standardkonstruktor) der Basisklasse aufgerufen.


3.1.10. Was sind anonyme Arrays?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ab Java 1.1 ist folgender Code g�ltig:

int i[];
i = new int[] {1, 2, 3};

Es ist jetzt also m�glich, Arrays auch au�erhalb der Definition mit den
gew�nschten Werten zu initialisieren, indem man mit {...} einfach die
Werte angibt, die das neue Array tragen soll.


3.1.11. Gibt es in Java einen Pr�-Prozessor wie in C++?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nein. In C++ existiert der sogenannte Pr�-Prozessor, der es mit
bestimmten Kommandos erlaubt, Teile des Codes zu �bersetzen und andere
Teile bei der �bersetzung zu �berspringen. Unter Umst�nden w�re es
hilfreich, wenn auch Java eine solche M�glichkeit der
Compilationssteuerung zulassen w�rde, doch einen Pr�-Prozessor gibt es
hier nicht. Man kann dies aber, zumindest ansatzweise, mit if-Statements
nachbilden. Dazu definiert man eine boolesche Variable DEBUG und in
Abh�ngigkeit von dieser Variablen sollen bestimmte Codeteile ausgef�hrt
werden, andere dagegen nicht.

public class Test {
    final static boolean DEBUG = true;

    public static void main (String[] params) {
        int i = 12;
        if (DEBUG) {
            System.out.println("Der Wert von i ist " + i);
        }
    }
}

Verwendet man nun noch Optimierer, die unbenutzten Code aus den
Klassendateien entfernen, so hat man im Prinzip ein �hnliches Verhalten
wie beim Pr�-Prozessor von C++. In diesem Zusammenhang ist es noch
erw�hnenswert, da� das Verfahren nur bei der if-Abfrage m�glich ist,
denn das Java-System pr�ft normalerweise darauf, ob Codezeilen erreicht
werden k�nnen oder nicht und gibt gegebenenfalls Fehlermeldungen aus.
Das if-Statement ist jedoch wie oben beschrieben erweitert worden, um
das gew�nschte Verhalten simulieren zu k�nnen. Dahingegen wird folgender
Code mit einer Fehlermeldung quittiert:

public class Test {
    final static boolean DEBUG = true;

    public static void main (String[] params) {
        int i = 12;
        while (DEBUG) {
            System.out.println("Der Wert von i ist " + i);
        }
    }
}

Denn es w�rde sich je nach Zustand von DEBUG eine Endlosschleife
ergeben.


3.1.12. Existiert der const Modifizierer von C++ auch in Java?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C++ kennt das Schl�sselwort const, das es erlaubt, konstante Objekte zu
definieren, deren Wert man nicht �ndern kann. Auf ein solches Objekt kann
man nur Methoden anwenden, die ebenfalls als const definiert sind, die
also die Daten des Objektes nicht �ndern k�nnen.

Ab Java 1.1 k�nnen Argumente mit dem Modifizierer final als konstant
definiert werden. Bei einer Objektreferenz bedeutet dies allerdings nur,
da� die Referenz konstant bleibt, nicht aber das Objekt, auf das die
Referenz verweist.

Da Java den Modifizierer const nicht kennt, ist es aber trotzdem recht
einfach m�glich, diesen nachzubilden. Alles, was man dazu braucht, ist
ein Interface, das die konstanten Methoden enth�lt, die das Objekt nicht
�ndern k�nnen. Will man nun ein konstantes Objekt zur�ckgeben oder
erzeugen, dann gibt man einfach eine Referenz vom Typ des Interfaces
zur�ck und schon hat man das Gew�nschte erzielt.

Folgendes Beispiel soll das Ganze etwas verdeutlichen:

interface KonstanterTyp {
    public int get();
}

public class NichtKonstanterTyp implements KonstanterTyp {

    int i;

    public void set(int i) {
        this.i = i;
    }

    public int get() {
        return this.i;
    }
}

Ein konstantes Object wird dann durch

    KonstanterTyp A = new NichtKonstanterTyp();

erzeugt.

Anmerkung: Im Prinzip wird hier durch das Interface eine Art Untermenge
der Klasse  NichtKonstanterTyp  definiert. Bei C++ l�uft dieser Proze�
im Prinzip auch so ab, nur wird hier vom Compiler automatisch diese
Untermenge durch den Modifizierer const erzeugt und der Programmierer
mu� sich hierum nicht k�mmern. In Java mu� man diesen Proze� selbst
durchf�hren.


3.1.13. Wie kann man Referenzen von �bergabeparametern �ndern?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Von Sprachen wie C++ oder Pascal kennt man die M�glichkeit, Referenzen,
die an die Methode �bergeben werden, innerhalb der Methode zu �ndern, an
die sie �bergeben wurden, wodurch nach dem Aufruf der Methode die
Referenzen auf andere Objekte verweisen.

In Java gibt es zwei M�glichkeiten, diesen Effekt zu erreichen:

  - Einf�hren einer weiteren Ebene mit Wrapper-Klassen, die spezielle
    Referenzen zur Verf�gung stellen.
  - Verwendung von eindimensionalen, einelementigen Arrays.

Der erste Punkt d�rfte klar sein, jedoch steht der Aufwand erst dann in
einem vern�nftigen Verh�ltnis zum Ergebnis, wenn diese Art der
Parametermodifikation �fter innerhalb des Programms vorkommt, denn
ansonsten lohnt sich das Design einer speziellen Klasse nicht unbedingt.
Den zweiten Weg verdeutlicht das folgende Programm:

public class Test {
    public void parameterModifikation(Object[] paramter) {
        parameter[0] = "Neue Referenz";
    }
    public static void main (String[] args) {
        Objcet parameter[] = new Object[1];
        parameter[0] = "Zu modifizierender Parameter."
        Test test = new Test();
        System.out.println(parameter[0]);
        test.parameterModifikation(parameter);
        System.out.println(parameter[0]);
    }

}

Das Beispielprogramm liefert folgende Ausgabe:

    Zu modifizierender Parameter
    Neue Referenz


3.1.14. Wie erzeuge ich eine  tiefe  Kopie eines Objektes mit m�glichst
        wenig Aufwand?
        Autor: Markus Reitz
        Autor: Ingo R. Homann
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Weist man einer Objektvariablen eine andere zu, so wird nur die Referenz
kopiert und beide Objektvariablen k�nnen das Objekt modifizieren und
diese Modifikation auch sehen. Dies ist das Standardverhalten von Java.
Durch clone() wird z.B. eine flache Kopie von dem Vector angelegt,
d.h. z.B. das Hinzuf�gen eines neuen Elements in die Kopie des Vektors
ist im Original-Vector nicht sichtbar. Die enthaltenen Objekte jedoch
werden *nicht* mitkopiert, d.h. �nderungen an den enthaltenen Objekten
sind in beiden Vectoren sichtbar. Wenn wirklich alles - also auch die
enthaltenen Objekte und die rekursiv darin enthaltenen Objekte - kopiert
werden soll, dann braucht man eine sog. tiefe Kopie.

Ein sehr eleganter Weg, eine tiefe Kopie eines Objektes zu erzeugen,
verwendet den Serialisierungs-Mechanismus. Objekte, die man mit diesem
Verfahren kopieren m�chte, m�ssen also das Interface Serializable
implementieren.

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

public class TiefeKopie {
    public static Object kopiere(Object einObjekt)
            throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);

        oos.write(einObjekt);

        ByteArrayInputStream bais =
                new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);

        return ois.readObject();
    }
}

Zuerst werden zwei Ausgabestr�me angelegt: Ein Byte-Strom und ein
Object-Strom. Der Byte-Strom wird hinter den Object-Strom geschaltet und
das zu kopierende Objekt wird auf dem Object-Strom ausgegeben und durch
die Verkn�pfung der beiden Str�me schlie�lich in den Byte-Strom
geschrieben. Dieser Byte-Strom wird dann mit einem zweiten Strom wieder
eingelesen und mit einem weiteren Object-Strom wird aus den einzelnen
Bytes wieder ein Objekt rekonstruiert. Die Ausgabe des Object-Stroms ist
dann das kopierte Objekt.

Die Anwendung der Klasse zeigt folgendes Codefragment:

public class Test {
    public static void main(String[] args) {
        int einArray[] = {56, 42, 67, 90, 12, 45};
        int tiefeKopieVonEinArray = (int[]) TiefeKopie.kopiere(einArray);
    }
}

Ein Array ist in Java nichts weiteres als ein Objekt und implementiert
auch das Serializeable-Interface, weshalb das obige Kopierverfahren
problemlos greifen kann.

Anmerkung: Bei komplexen Objekten, die viele Referenzen auf andere
Objekte besitzen schl�gt das Verfahren meist fehl. Der
Serialisierungsmechanismus verwendet Rekursion, um alle referenzierten
Objekte zu speichern. Wird auf Objekte referenziert, die wieder auf
Objekte referenzieren usw. kann es geschehen, da� der Stack-Speicher
f�r die Rekursion �berl�uft. Diese elegante Methode der tiefen Kopie
kann also nur bei  einfachen  Objekten angewendet werden. In Sachen
Performance liegt diese L�sung jedoch um einiges hinter der klassischen
L�sung alle Elemente einzeln zu kopieren. Dessen sollte man sich klar
sein, wenn man diese L�sung einsetzt.


3.1.15. Wie kann ich in Java eine dem Programmierer unbekannt Anzahl
        gleichartiger Objekte erzeugen und ihnen passende Namen zuweisen,
        also label1, label2 usw.?
        Autor: Michael Paap, Christian Kaufhold
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das ist in dieser Form nicht sinnvoll. Die bessere L�sung
besteht in der Verwendung eines Arrays. In Java kann die
Gr��e eines Arrays bei seiner Erzeugung zur Laufzeit
(einmalig!) festgelegt werden. Ein Zugriff auf die einzelnen
Objekte erfolgt dann �ber den Arrayindex:


// Deklaration
Label[] myLabels;

...

// Erzeugung und Initalisierung zur Laufzeit
int anzahl = 10;
myLabels = new Label[anzahl];

for (int i = 0; i < myLabels.length; i++) {
    myLabels[i] = new Label("Label Nr. " + i);
}

// Verwendung
myLabel[3].setBackground(Color.red);


3.1.16. Wie kann ich den Typ enum aus C++ in Java umsetzen?
        Autor: Markus Reitz, Uwe G�nther, Ulf J�hrig
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

C++ bietet einen sogenannten Enumerationstyp. Eine Variable eines
solchen Typs kann nur definierte Werte annehmen, die mit symbolischen
Namen bezeichnet werden. Folgende Enumeration k�nnte zum Beispiel f�r
eine Ampel verwendet werden:

    enum Ampel {ROT, GELB, GRUEN};

Java bietet diesen Typ nicht, kann diesen aber recht einfach mit einem
Interface nachbilden:

interface Ampel {
    public static final int ROT = 1;
    public static final int GELB = 2;
    public static final int GRUEN = 3;
}

Ein C++ Compiler f�hrt automatisch die Zuordnung von Variablennamen zu
eindeutigen Zahlenwerten durch, in Java mu� der Programmierer diesen
Proze� erledigen. Die Verwendung differiert zwischen Java und C++:

    Ampel eineVariable = ROT; // Das ist C++
    int eineVariable = Ampel.ROT; // Das ist Java

Man erkennt einen gro�en Nachteil der Java-Version: Da es sich um eine
int-Variable handelt, ist es prinzipiell m�glich, jeden Wert an diese
Variable zuzuweisen, eben nicht nur Werte aus dem Wertebereich rot, gruen
und gelb. Im Gegensatz dazu l��t ein C++-Compiler nur Zuweisungen von
Symbolen aus dem Enumerationstyp zu. Insofern ist die Nachbildung in Java
weniger sicher als das C++-Pendant und sollte daher mit Vorsicht
angewendet werden. Sprich sie ist nicht Typsicher!

Wie schon oben angesprochen, bietet diese direkte Implementierung den
Nachteil, da� sie nicht typsicher ist. Doch es ist recht einfach m�glich,
mit Java eine typsichere Implementierung zu erhalten:

public final class Ampel {

    private String name;
    public final int ord;
    private static int obereGrenze = 0;

    private Ampel(String name) {
        this.name = name;
        this.ord = obereGrenze++;
    }

    public String toString() {
        return this.name;
    }

    public static int groesse() {
        return this.obereGrenze;
    }

    public static final Ampel ROT = new Ampel("Rot");
    public static final Ampel GELB = new Ampel("Gelb");
    public static final Anpel GRUEN = new Ampel("Gruen");
}

Besonders interessant ist hier die Kombination von automatischer
Zuweisung eines eindeutigen Zahlenwertes mit den Symbolwerten eines
Strings.

Auf den ersten Blick sieht die Klassendefinition ziemlich kompliziert und
unverst�ndlich aus, das Prinzip ist jedoch nicht schwer zu verstehen:

  - Zuersteinmal ist die Klasse als final deklariert, wodurch verhindert
    wird, da� von dieser Klasse Ableitungen gebildet werden k�nnen. Der
    Aufz�hlungstyp kann also - weder absichtlich noch unabsichtlich -
    durch Vererbung ver�ndert werden.

  - Der Konstruktor der Klasse ist private, dadurch kann er nur von
    der Klasse selbst aufgerufen werden. Damit sind die einzigen
    Instanzen, die von Ampel erzeugt werden k�nnen, die, die den
    public-Variablen der Klassen zugewiesen sind.

  - Einer Referenz vom Typ Ampel k�nnen durch diese Ma�nahmen nur die
    Werte {ROT, GELB, GRUEN} zugewiesen werden, andere Instanzen vom
    Typ Ampel sind ausgeschlossen, weil sie niemals existieren werden.

  - Die �berlagerung von toString hat den Zweck, einem das Leben beim
    Debuggen einfacher zu machen.

Will man nun diesen Typ von Enumeration benutzen, so sieht das in etwa
wie folgt aus:

public class Test {
    public static void main(String[] args){
        Ampel meineAmpel = Ampel.ROT;

        if (meineAmpel == Ampel.ROT) {
            System.out.println("Ampel ist " + meineAmpel + ". ");
            System.out.println("Anhalten!");
        }
        if (meineAmpel == Ampel.GELB) {
            System.out.println("Ampel ist " + meineAmpel + ". ");
            System.out.println("Motor starten -oder- Anhalten!");
        }
        if (meineAmpel == Ampel.GRUEN) {
            System.out.println("Ampel ist " + meineAmpel + ". ");
            System.out.println("Gib Gas!");
        }
    }
}

Dieser Typ der Enumeration verwendet also Referenzen und nicht, wie
Version 1, int-Werte, die nicht typsicher sind. Durch die
Typpr�fungsmechanismen von Java wird diese Art von Enumeration
vollkommen typsicher und steht dem enum Konstrukt von C++ nun in nichts
mehr nach.

Wer mehr �ber dieses Pattern erfahren m�chte sei dem sei folgender Link
empfohlen:

<URL:http://www.javaworld.com/javaworld/jw-07-1997/jw-07-enumerated.html>


3.1.17. Kann man Mehrfachvererbung mit Java simulieren?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java kennt im Gegensatz zu C++ nicht das Feature der Mehrfachvererbung,
eine Klasse kann nur genau einen Vorfahren haben, im Gegensatz zu
beliebig vielen bei Mehrfachvererbung.

H�ufig liest man, da� man die Mehrfachvererbung mit Hilfe von Interfaces
nachbilden kann, indem man die Methodenschnittstelle der einzelnen
Klassen als Interfaces definiert und diese Interfaces alle gleichzeitig
von der fraglichen Klasse implementieren l��t, denn dies ist in Java
m�glich.

Mit Mehrfachvererbung hat dies aber nichts zu tun, wenn man den
eigentlichen Sinn und Zweck von Vererbung betrachtet. Vererbung ist
eines der m�glichen Prinzipien, um die Codewiederverwertung zu
garantieren. Code, der in mehreren Klassen ben�tigt wird, ist nur in der
Basisklasse aufgef�hrt und durch die Vererbung k�nnen die  Erben  auch
diesen Code benutzen. Der Code steht also nur an einer Stelle. Bei der
oben beschriebenen  Nachbildung  wird in keiner Weise Code gespart, denn
die Methoden der Interfaces m�ssen ja von der Klasse noch implementiert
werden.

In diesem Sinne kann man Mehrfachvererbung nicht in Java nachbilden.


3.1.18. Wie realisiere ich eine variable Parameterliste?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Es gibt Anwendungsf�lle, in denen es �u�erst n�tzlich w�re, einer
Methode eine variable Anzahl an Parametern �bergeben zu k�nnen. Ein
Anwendungsfall w�re eine Klasse beliebig-dimensionaler Vektoren. Ein
Konstruktor dieser Klasse m��te die Initialisierung eines Vektors mit
bestimmten Werten erlauben und da beliebig-dimensionale Vektoren von
dieser Klasse verarbeitet werden, m��te der Konstruktor mit einer
variablen Parameteranzahl arbeiten k�nnen. Mit einem Trick kann man eine
variable Parameterliste realisieren: Man �bergibt der Methode ein Array
von Referenzen auf die Klasse Object. Da in Java alle Objekte von der
Klasse Object abstammen - sie ist quasi die Klasse aller Klassen - kann
das Array Referenzen auf beliebige Objekte aufnehmen. Innerhalb der
Methode kann dann mit dem length-Feld des Arrays die Anzahl der
�bergebenen Parameter ermittelt werden. Mit dem instanceof-Operator von
Java kann dann der Typ des Objekts ermittelt werden, auf den die
Referenzen verweisen und an Hand dieser Informationen kann man dann
festlegen, was getan werden soll. Ein Programmfragment verdeutlicht das
bisher Gesagte:

public class Test {
    void methodeMitVariablerParameterListe(Object[] parameterList) {
        //L�nge: parameterList.length ===> Anzahl der Parameter
        //Typ:   if (parameterList[i] instanceof <Type>)
    }
}

Ein Nachteil ist offensichtlich: Es kann nur genau eine Methode mit
variabler Parameterliste geben bzw. innerhalb dieser einen Methode m�ssen
alle Variationen ber�cksichtigt und implementiert werden, was nicht
unbedingt zur �bersichtlichkeit des Programms beitr�gt.

Ein Aufruf der Methode gestaltet sich nun wie folgt:

Test obj = new Test();
obj.methodeMitVariablerParameterListe(new Object[] {
        paramObject1, paramObject2, ..., paramObjectn
    });

Will man elementare Datentypen wie double oder int an die Methode
�bergeben, so mu� man die zugeh�rigen Wrapper-Klassen verwenden, die
diese elementaren Datentypen in Klassen  einpacken.


3.1.19. Wie realisiere ich eine Methodenauswahl nach den dynamischen
        Parametertypen?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java w�hlt Methoden nach dem statischen Typ der �bergabeobjekte aus. Man
kann jedoch eine dynamische Auswahl simulieren, indem man das oben
angesprochene Prinzip der variablen Parameter hierauf �bertr�gt. Man
pr�ft die �bergebenen Referenzen mit dem instanceof-Operator, der den
dynamischen Typ des Parameters liefert. Anhand dieser Informationen kann
man dann ein  dynamisches  Verhalten der Methodenaufrufe realisieren.
Auch hier gilt, wie auch schon bei der variablen Parameterliste, da� eine
einzige Methode alle Aufrufm�glichkeiten abdecken mu�.


3.1.20. Sind Methoden in Java immer virtuell?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In Java sind alle Methoden virtuell, eine Unterscheidung zwischen
virtuellen und nicht-virtuellen Methoden wie zum Beispiel in C++, gibt es
in Java nicht. Ist es f�r die Funktionsweise eines Objektes wichtig, da�
die vorhandenen Methoden nicht �berschrieben werden k�nnen - etwa um zu
verhindern, da� sich die Funktionalit�t des Objekts dadurch grundlegend
�ndern l��t - so mu� man entsprechende Methoden mit dem Modifizierer
final deklarieren, der ein �berschreiben verhindert.


3.1.21. Ich stosse ab und zu auf den Begriff "Wrapper-Klassen".
        K�nnte mir jemand erkl�ren was das ist?
        Autor: Stephan Menzel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Eine sehr gute Frage, auf die ich mal mit einem Zitat aus Go to Java 2
antworten moechte, denn sie wird zu selten gestellt:

Zitat (Goto Java 2):

Zu jedem primitiven Datentyp in Java gibt es eine korrespondierende
Wrapper-Klasse. Diese kapselt die primitive Variable in einer
objektorientierten H�lle und stellt eine Reihe von Methoden zum Zugriff
auf die Variable zur Verf�gung. Zwar wird man bei der Programmierung
meist die primitiven Typen verwenden, doch gibt es einige Situationen,
in denen die Anwendung einer Wrapper-Klasse sinnvoll sein kann.

Diese Klassen, wie zum Beispiel "Integer" koennen einem das Leben
angenehmer gestalten, wenn man Dinge tun muss, die man mit einfachen
ints tun will, aber mangels vorhandener Methoden nicht kann, weil diese
Primitiven eben keine richtigen Objekte sind.

Zum Beispiel kann Integer (im Gegensatz zu int) Strings nach Zahlen
parsen, oder Integers als Binaercode ausgeben oder als Hex oder in
andere Zahlentypen umwandeln und vieles mehr. Vielleicht ist es fuer
Dich noch interessant zu erfahren, dass diese Wrapper Klassen in der
Praxis oftmals nicht instantiiert, sondern ihre Methoden statisch
aufgerufen werden.

Um zum Beispiel aus dem String "42" das betreffende int zu machen,
rufst Du:

String zweiundvierzig = new String ("42") ;
int answer = Integer.parseInt (zweiundvierzig) ;

Das brauchst Du zum Beispiel zum Auswerten von GUI-Zahlenfeldern.
Ich hoffe, ich konnte ein wenig Licht ins Dunkel bringen. Das
Verstaendnis von Wrapperklassen und deren Sinn halte ich naemlich fuer
essentiell, wenn man mit OOP beginnt.


3.1.22. Warum ist private nicht privat?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public class Person {

    private int kontostand;

    public Person(int kontostand) {
        this.kontostand = kontostand;
    }

    public void addGehalt(int gehalt) {
        this.kontostand += gehalt;
    }

    public void klauen(Person opfer) {
        this.kontostand += opfer.kontostand;
        opfer.kontostand = 0;
    }

    public void zeigeKontostand() {
        System.out.println("Kontostand: " + this.kontostand);
    }
}


public class Test {
    public static void main(String[] args) {
        //Der Dieb er�ffnet ein Konto
        Person dieb = new Person(10);

        //Das Opfer er�ffnet ein Konto
        Person opfer = new Person(50000);

        //Das Opfer bekommt Gehalt
        opfer.addGehalt(10000);

        //Der Dieb geht an die Arbeit
        dieb.klauen(opfer);

        //Das opfer ist nun pleite!!!
        opfer.zeigeKontostand();

        //Und der Dieb un 60000 Euro reicher.
        dieb.zeigeKontostand();
    }
}


Wenn man obiges Programm testet, so wird man feststellen, da� es m�glich
ist, die private-Datenfelder eines Objektes zu manipulieren; diese Daten
sind also nicht privat im sonst �blichen Sinne. Allerdings ist die
Privatsph�re nur f�r Objekte der gleichen Klasse aufgehoben, Objekte
anderer Klassen haben keinen Zugriff auf die private-Daten von Objekten
anderer Klassen. Damit ist obige M�glichkeit nicht weiter tragisch, denn
der Entwickler der Klasse kann eine wie oben gezeigte M�glichkeit
wirksam unterbinden. Wenn er dies nicht tut, so ist die Schuld bei ihm
zu suchen, denn nur der Entwickler allein ist f�r das Verhalten der
Klassen zust�ndig und nur der Entwickler mu� solche M�glichkeiten durch
das Design ausschlie�en. Die private-Deklaration ist damit als
Deklaration der Privatsph�re gegen�ber Objekten anderer Klassen zu
sehen, zwischen Objekten der gleichen Klasse herrscht ein
freundschaftliches Verh�ltnis, sie d�rfen sich gegenseitig in die Daten
schauen.





3.2. [STRING] - Fragen die unmittelbar mit Strings zu tun haben.
----------------------------------------------------------------

3.2.1. Wie vergleiche ich zwei Strings in Java?
       Autor: Markus Reitz, Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:

Man versucht zwei Strings in der Form

if(stringEins == stringZwei) {
    System.out.println("stringEins und stringZwei sind gleich.");
}

zu vergleichen und erh�lt alles andere als ein richtiges Ergebnis.

Der Grund ist der, da� mit dem "=="-Operator nur die beiden Referenzen
miteinander verglichen werden, nicht jedoch die Objekte. Man erh�lt
deshalb wom�glich auch bei zwei gleichen Strings das Ergebnis, da� sie
verschieden sind. F�r den inhaltlichen Vergleich, nicht nur von Strings,
sondern allgemein von Objekten, wird in Java die Methode
equals(Object obj) verwendet, die nicht immer nur Referenzen, sondern
je nach Klasse auch die Inhalte (sprich ihre Daten) vergleicht. Obige
Abfrage m��te also

if(stringEins.equals(stringZwei)) {
    System.out.println("stringEins und stringZwei sind gleich.");
}

lauten, damit das gemacht wird, was eigentlich gew�nscht ist.


Im Zusammenhang mit Strings ist noch eine Besonderheit zu erw�hnen:

if ("Java".equals(stringZwei)) {
    System.out.println("stringZwei ist gleich zu Java.");
}

ist zul�ssig, der Compiler erzeugt aus
der Zeichenkette automatisch ein String-Objekt; man mu� also nicht
zuerst ein Objekt anlegen und den String Java dort speichern.


3.2.2. Wie wandle ich einen String in einen Integer?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Klassen k�nnen Methoden besitzen, die die Konvertierung eines Objekts
dieser Klasse in ein Objekt einer anderen Klasse �bernehmen. Zu dem
elementaren Java-Datentyp int gibt es eine sogenannte Wrapper-Klasse
Integer, die den elementaren Datentyp in einer Klasse kapselt .Diese
Klasse stellt eine Methode (in diesem Fall eine Klassenmethode) zur
Verf�gung, die das Gew�nschte leistet:

public class Test {
    public static void main (String[] params) {
        String stringMitZahl = "50";
        int zahl = 0;
        try {
            zahl = Integer.parseInt(stringMitZahl);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        zahl = zahl + 10;
        System.out.println("Die Variable zahl = " + zahl);
    }
}


3.2.3. Wie wandle ich einen Integer in einen String um?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dieses Problem ist genau das Gegenteil des vorherigen. Wie die Klasse
Integer, so besitzt auch die Klasse String eine Methode, die das
Problem l�st, allerdings hei�t die Methode nicht parseString, was man
analog schlie�en k�nnte, sondern valueOf.

public class Test {
    public static void main (String[] params) {
        int zahl = 50;
        String stringMitZahl = String.valueOf(zahl);
        System.out.println("Die Variable stringMitZahl = " +
                stringMitZahl);
    }
}


3.2.4. Wie wandle ich einen Integer in einen HexString um?
       Autor: Uwe G�nther
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das Problem ist �hnlich wie das Konvertieren von einem Integer in einen
String. Wie die Klasse String die Klassenmethode valueOf besitzt, um
einen String zu erzeugen, so besitzt die Klasse Integer die
Klassenmethode toHexString(int i).

public class Test {
    public static void main (String[] params) {
        int zahl = 50;
        String stringAlsHex = Integer.toHexString(zahl);
        System.out.println("Die Variable stringAlsHex = " +
                           stringAlsHex);
    }
}

Der Nachteil der Integer.toHexString(int i) Methode ist, dass sie alle
f�hrenden Nullen einer Hex-Repr�sentation abschneidet.


3.2.5. Wie kann ich eine Zahl formatieren und wie lege ich die Anzahl der
       Nachkommastellen fest?
       Autor: Karsten Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das kann die Klasse java.text.NumberFormat und deren Abk�mmlinge
erledigen.

Beispiel:

import java.text.DecimalFormat;

public class Zahl {
    public static void main(String[] args) {
        double betrag = 1000d/3d; // -> 333.333333...
        DecimalFormat df = new DecimalFormat("#.##");
        System.out.println(df.format(betrag));
        df = new DecimalFormat("#.## DM");
        System.out.println(df.format(betrag));
        df = new DecimalFormat("0000.0000");
        System.out.println(df.format(betrag));
    }
}

Die Ausgabe des Programms sind formatierte Dezimalzahlen:
333,33
333,33 DM
0333,3333

In der API-Dokumentation der Klassen java.text.Decimalformat und
java.text.NumberFormat werden alle weiteren Formatierungsoptionen
erl�utert. Falls die Umwandlungen von double nach String
zeitkritisch durchgef�hrt werden m�ssen, lohnt sich ein Blick auf
<URL:http://www.onjava.com/pub/a/onjava/2000/12/15/formatting_doubles.html>
Dort erkl�rt Jack Shirazi (Autor des Buches "Java Perfomance Tuning")
andere Konvertierungsmethoden.


3.2.6. Wie kann ich ein Datum formatieren?
       Autor: Karsten Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das machen andere f�r Dich,...

Benutze einfach die Klassen DateFormat aus dem package java.text.
Folgendes Beispiel zeigt Dir die Anwendung der SimpleDateFormat-Klasse:

import java.util.Date;
import java.text.SimpleDateFormat;

public class Datum {
    public static void main(String[] args) {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(sd.format(new Date()));
        sd.applyPattern("dd.MM.yyyy");
        System.out.println(sd.format(new Date()));
    }
}

Die Ausgabe des Programms sind formatierte Dat�mer:

    2000-12-24
    24.12.2000

In der API-Dokumentation zur Klasse java.text.SimpleDateFormat sind die
K�rzel der verschiedenen Datumskomponenten f�r Tag, Monat, usw.
aufgef�hrt.


3.2.7. Wie kann ich in einem String oder StringBuffer mehrere Zeichen
       suchen und ersetzen?
       Autor: Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mit

    String String#replace(char,char)

kann ich nur einzelne Zeichen suchen und mit

    StringBuffer replace(int,int,String)

nur ersetzen aber nicht suchen.

L�sung:

Eine gute Hausaufgabe. Was man hier braucht, ist eine Kombination von

    int String#indexOf(String,int),
    String String#substring(int,int)

mit einem neu aufzubauenden StringBuffer.

bzw.

    int StringBuffer#indexOf(String,int)
    StringBuffer#replace(int,int,String)


Die folgende L�sung ist eine unter vielen und ersetzt alle Vorkommen von
"search" in "source" mit "replace":

public static String replaceAll(String source, String search,
                                String replace) {
    if(search.equals(replace)) {
        return source; //kann ja sein, dass wir nichts tun m�ssen
    }

    StringBuffer result = new StringBuffer();
    int len = search.length();
    if(len == 0) {
        return source; //verhindert Endlosschleife bei search.equals("");
    }

    int pos = 0; //position
    int nPos;    //next position
    do {
        nPos = source.indexOf(search, pos);
        if(nPos != -1) { //gefunden
            result.append(source.substring(pos, nPos));
            result.append(replace);
            pos = nPos+len;
        } else { //nicht gefunden
            result.append(source.substring(pos)); //letzter abschnitt
        }
    } while(nPos!= -1);

    return result.toString();
}

Da sowas praktisch �berall gebraucht wird, gibt es unz�hlige
Bibliothek(chen) im Netz, die so etwas anbieten, z.B.

<URL:http://ostermiller.org/utils/StringHelper.java.html>

BTW: Der Link muss as den 3 Zeilen zusammen gestzt werden!

[...vielleicht noch mehr und geeignetere Adressen...]



3.2.8. Gibt es regul�re Ausdr�cke in Java (regular expressions)?
       Autor: Karsten Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ja, nat�rlich.

Bis zum J2SDK 1.4 muss man, um regul�re Ausdr�cke in Java zu benutzen,
auf externe packages zur�ckgreifen. Eines der ausgereiftesten ist das
Regexp-Paket aus dem Jakarta-Projekt:

    http://jakarta.apache.org/regexp/index.html

Ab dem J2SDK 1.4 wird es jedoch ein package java.util.regex geben, das
somit die M�glichkeit zur Benutzung der regul�ren Ausdr�cke direkt in die
Klassenhierarchie einbaut.

Nachfolgend ein Beispiel f�r die Nutzung dieses packages (Achtung:
funktioniert nur ab J2SDK 1.4 aufw�rts!).

Das Beispielprogramm zeigt, wie in der Stringvariablen 'input'
nach einem Muster (Pattern) gesucht wird, das auf einer Ziffer,
mindestens einem Buchstaben und einer weiteren Ziffer besteht:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternTest {

    public static void main(String[] args) {
        String input = "Test f�r Regex Ausdr�cke 1xxx2 n444n.";
        Pattern p = Pattern.compile("\\d\\D+\\d");
        // Muster: Ziffer, mind. ein Buchstabe, Ziffer
        Matcher m = p.matcher(input);
        if (m.find()) {
            System.out.println("Muster an Pos. " + m.start());
                System.out.println("Muster ist: " + m.group());
        } else {
            System.out.println("Muster nicht gefunden");
        }
    }
}

Die Ausgabe dieses Programms ist:

    Muster an Pos. 25
    Muster ist: 1xxx2

Weitere Infos in der API-Dokumentation zu java.util.regex.




3.3. [IO] - Frage bez�glich Eingabe/Ausgabe, Streams, etc. in Java.
-------------------------------------------------------------------

3.3.1. Verlangsamt Serialisierung mein Programm?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java bietet mit dem Mechanismus der Serialisierung auf einfache Weise
die M�glichkeit, den aktuellen Zustand des Objekts auf einem
Datentr�ger, das Netz oder sonst wohin �ber einen Stream zu sichern. Der
verwendete Mechanismus ist relativ kompliziert, damit auch alle
auftretenden M�glichkeiten korrekt behandelt werden k�nnen. Sind die
Daten der Objekte sehr gro�, so empfiehlt es sich, eigene Prozeduren
zur Speicherung zu entwickeln, die dann nicht mehr allgemeing�ltig, aber
auf die aktuelle Verwendung angepa�t und damit schneller sind.


3.3.2. Wie kann ich rekursiv einen Verzeichnisbaum abarbeiten?
       Autor: Marco Schmidt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In java.io.File befinden sich die dazu ben�tigte Funktionalit�t. Mit
list() l��t man sich ein Array mit allen Dateinamen geben, mit
isDirectory() l��t sich pr�fen, ob es sich bei dem File-Objekt um ein
Verzeichnis handelt. Indem man nun rekursiv in Unterverzeichnisse
absteigt, kann man so einen kompletten Verzeichnisbaum abarbeiten.

Hier ein Beispielprogramm (scantree.java):

import java.io.File;

public class scantree {
    public static void main(String[] args) {
        // Programm muss einen Verzeichnisnamen als Parameter haben
        File dir = new File(args[0]);
        scan(dir);
    }

    public static void scan(File dir) {
        // Liste aller Dateien und Unterverzeichnisse holen
        String[] entries = dir.list();
        if (entries == null || entries.length < 1) {
            return;
        }
        for (int i = 0; i < entries.length; i++) {
            File entry = new File(dir, entries[i]);
            if (entry.isDirectory()) {
                scan(entry); // rekursiv ins Unterverzeichnis verzweigen
            } else {
                // entry ist eine Datei
                System.out.println(entry);
            }
        }
    }
}


3.3.3. Wie kann ich aus Dateien zeilenweise lesen?
       Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generell nutzt man f�r die Datei-Operationen einen Buffered Reader oder
eine Klasse, die von dieser abstammt. Diese Klasse besitzt dann die
Methode readLine(), die eine Zeile aus der Datei ausliest und diese Zeile
als einen String zur�ckgibt.

Zu beachten ist, da� bei Erreichen des Dateiendes kein leerer String,
sondern eine Nullreferenz zur�ckgegeben wird. Ein Programm, da� aus einer
Datei zeilenweise liest, sieht in Java wie folgt aus:

import java.io.*;

public class ZeilenWeiseLesen {
    public static void main(String[] args) {
        try {
            String zeile;

            //Wir lesen aus "eingabe.txt".
            File eingabeDatei = new File("eingabe.txt");
            FileReader eingabeStrom = new FileReader(eingabeDatei);
            BufferedReader eingabe = new BufferedReader(eingabeStrom);

            while ((zeile = eingabe.readLine()) != null) {
                System.out.println(zeile);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


3.3.4. Wie kann ich Exponentialzahlen (z.B. 1.09E+008) aus einer Datei
       lesen?
       Autor: Wolfram R�haak
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mit Java f�hrt folgendes Verfahren zum Ziel:
Lies die Daten als Strings ein und wandel sie mittels
Double.valueOf(my_string).doubleValue()
in einen double Wert um.

Das StreamTokenizer keine Exponentialzahlen kennt hat von Sun Bug Status
bekommen (obgleich der StreamTokenizer so arbeitet wie angegeben):
* BugId: #4079180
  Synopsis:  java.io.StreamTokenizer: Add ability to read full Java
  floating-point syntax
  Der Sun Workaround soll wohl ein:
      public void parseExponentialNumbers(boolean flag)
   sein.

Beispiel:
import java.io.*;
import java.util.Vector;
/**
 * @author Wolfram R�haak
 * Beispielcode, der zeigt wie man Zahlen aus einer Datei liest.
 * Die Datei darf in diesem Fall nur Zahlen enthalten, getrennt durch
 * Tabulator oder Space.
 * Die Anzahl von Spalten/Zeilen ist nicht vorgegeben.
 * Um *.cvs Kompatibil�t zu erhalten kann man als whitespaceChars
 * noch ',' und ';' hinzuf�gen.
 */
public class ReadExponential {

    int ni; // Anzahl Zeilen
    int nj; // Anzahl Spalten

     private ReadExponential(String Filename) {
         int i=0;
         int j=0;
         Vector v2 = new Vector();

         try {
             FileInputStream fis = new FileInputStream(Filename);
             BufferedReader r =
                     new BufferedReader(new InputStreamReader(fis));
             StreamTokenizer st  = new StreamTokenizer(r);
             /*
              * Nachfolgendes Code-Fragment von:
              * Mark Gritter (mgritter@pup16.stanford.edu)
              * Betrifft:Re: This is easy in C++ (asking for help)
              * Newsgroups:comp.lang.java.programmer
              * Datum:1997/11/07
              */
             st.resetSyntax();
             st.whitespaceChars(' ', ' ');
             st.whitespaceChars('\n', '\n');
             st.wordChars('0','9');
             st.wordChars('e','e');
             st.wordChars('E','E');
             st.wordChars('.','.');
             st.wordChars('+','+');
             st.wordChars('-','-');
             /* Ende Code-Fragment */
            st.eolIsSignificant(true);

            try {
                while(st.nextToken() != st.TT_EOF) {
                    String s1 = st.sval;
                    if(s1!=null) {
                        // Wert in Vector schreiben
                        v2.addElement(s1);
                        // Anzahl von Zeilen
                        i=st.lineno();
                    }
                }
            } catch(IOException ioe) {}
        } catch (FileNotFoundException fnfe) {}
        ni = i - 1;
        nj = ((v2.size())/(ni+1))-1;   // Anzahl von Spalten berechnen

        double[][] dAllValues = new double [ni+1][nj+1];
        int k=0;
        for(i = 0;i <= ni; i++) {
            for(j = 0;j <= nj; j++) {
                Object f = v2.elementAt(k); // Vector in
                String s = f.toString();    // Array umspeichern
                /*
                 * Double.valueOf(String s) kann jeden numerischen Wert
                 * von String nach double umwandeln
                 */
                dAllValues[i][j] = Double.valueOf(s).doubleValue();
                k++;
            }
        }
    }
}


3.3.5. Wie kann ich mit Java Dateien kopieren?
       Autor: Martin Erren, Uwe G�nther, Ulf J�hrig, Christian Kaufhold
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bestimmt die performanteste L�sung w�re, mit

 System.exec(...)

die Aufgabe dem Betriebssystem zu �bergeben.

Der Nachteil ist hier, dass so schwer ein plattformunabh�ngiger
Code erreichbar ist und die Fehlerbehandlung schwierig wird.

Deshalb einfach eine Datei lesen und in eine andere, neue
Datei schreiben, z.B. so:

import java.io.*;

public static void copyFile(File src, File dest, int bufSize,
        boolean force) throws IOException {
    if(dest.exists()) {
        if(force) {
            dest.delete();
        } else {
            throw new IOException(
                    "Cannot overwrite existing file: " + destName);
        }
    }
    byte[] buffer = new byte[bufSize];
    int read = 0;
    InputStream in = null;
    OutputStream out = null;
    try {
        in = new FileInputStream(src);
        out = new FileOutputStream(dest);
        while(true) {
            read = in.read(buffer);
            if (read == -1) {
                //-1 bedeutet EOF
                break;
            }
            out.write(buffer, 0, read);
        }
    } finally {
        // Sicherstellen, dass die Streams auch
        // bei einem throw geschlossen werden.
        // Falls in null ist, ist out auch null!
        if (in != null) {
            //Falls tats�chlich in.close() und out.close()
            //Exceptions werfen, die jenige von 'out' geworfen wird.
            try {
                in.close();
            }
            finally {
                if (out != null) {
                    out.close();
                }
            }
        }
    }
}


Das schwierigste ist hier wohl die Fehlerbehandlung, die je nach
Anforderung unterschiedlich sein kann.

Anmerkung: Ein paar exotische VMs optimieren read(byte[]) bzw.
write(byte[]) nicht, so dass hier ein BufferedInputStream oder
BufferedOutputStream evtl. angebracht ist.


3.3.6. Warum kann ich meine Bilder nicht mehr laden, nachdem ich sie in
       ein Jar gesteckt habe?
       Autor: Martin Erren, Paul Ebermann
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Auf Ressourcen in einer Jar-Datei kann man nicht mit File und 
FileInputStream zugreifen. Stattdessen gibt es einen allgemeineren 
Mechanismus, der Daten von dort holt, wo auch die Klassen hergeholt 
werden:

    URL Class#getResource(String)

und

    InputStream Class#getResourceAsStream(String)

sind Deine Freunde. Laut API-doc ist "/img.jpg" relativ zur codeBase,
also dem aktuellen Eintrag im CLASSPATH, wo Deine Klasse geladen wurde,
und "img.jpg" relativ zur Klasse, also im selben Verzeichnis, wo auch
die Klasse liegt.

Ob Applikation oder Applet, *.jar oder file-system spielt hier keine
Rolle.

mit

    System.out.println(MyClass.class.getResource("/").toString());

kannst Du jederzeit feststellen, welche codebase die jeweilige Klasse
hat.

Weiterhin sind

    InputStream ClassLoader.getSystemResourceAsStream(name);

und

    URL ClassLoader.getSystemResource(name)

f�r eigene Ressourcen nicht zu empfehlen, da man nicht immer seine eigene
Klasse vom SystemClassLoader l�dt (und nur dann w�ren die Ressourcen an 
der gesuchten Stelle).



3.4. [NET] - Frage bez�glich Netzwerk.
--------------------------------------

3.4.1. Wie kann ich einen Ping in Java realisieren?
       Autor: Stephan Menzel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Eigentlich gar nicht. Ein Ping (ICMP) ist eine hardwarenahe
Angelegenheit, die im Gegensatz zu dem hardwarefernen abstrahierenden
Konzept von Java steht. Die Antworten einer Netzwerkkarte sind da nicht
so sehr relevant, wie ein im Netzwerk vorhandener Dienst. So kann zum
Beispiel ein Rechner auf Pings nicht antworten und trotzdem einen Dienst
anbieten. Oder die Pings verenden an einer Firewall oder aber der Rechner
auf dem das Programm laeuft, ist gar nicht in der Lage, zu pingen.
Das bedeutet, es ist sicherer und besser, einfach eine Testweise
Socketverbindung zu der betreffenden Zieladresse aufzubauen und eine
evtl. auftretende Exception als Zeichen fuer dessen Abwesenheit im Netz
zu deuten.

Folgendes Beispiel soll dies zeigen:

import java.io.*;
import java.net.*;
..

 static Socket nntpsock; // Der Socket fuer die Newsverbindung
 static BufferedReader in;
 static OutputStreamWriter out;

...

try {
    nntpsock = new Socket("news.cis.dfn.de", 119); // Verbinden
    nntpsock.setSoTimeout(300); // Timeout auf 300ms
    in = new BufferedReader(
            new InputStreamReader(nntpsock.getInputStream()));
    out = new OutputStreamWriter(nntpsock.getOutputStream());
} catch (UnknownHostException e) {
    System.err.println("Unknown Host.:" + e.toString());
} catch (IOException e) {
    System.err.println("Rechner nicht erreichbar.  :" + e.toString());
}

...






3.5. [AWT] - Frage bez�glich AWT.
---------------------------------

3.5.1 Wenn ich einen Listener bei mehreren Buttons anmelde, wie kann ich
      dann unterscheiden, welcher gedr�ckt wurde?
      Autor: Michael Paap, Christian Kaufhold, Georg Lippitsch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wenn Du so vorgehst wird, egal welcher Button geclickt wird, die Methode
actionPerformed(ActionEvent ev) des Listeners aufgerufen.

Mit ev.getSource() bekommst Du nun eine Referenz auf die Ereignisquelle
(als Object). Dann kannst Du schauen, welcher Button geclickt wurde,
z.B. indem Du diese Ereignisquelle mit den vorhandenen Buttons
vergleichst oder indem Du auf Button castest und ihre Beschriftung
ausliest.

Beispiel:

Angenommen, Du hast einen ActionListener bei jedem Button
eines Arrays von 4 Buttons registriert. Dann k�nnte die
Methode actionPerformed im Listener wie folgt aussehen:

public void actionPerformed(ActionEvent ev) {
    int pressed = -1;
    for (int i=0; i<myButtons.length; i++) {
        if (myButtons[i] == ev.getSource()) {
            pressed = i;
            break;
        }
    }

    // hier abh�ngig von pressed verschiedene Aktionen
    // ausf�hren
}

oder so:

public void actionPerformed(ActionEvent ev) {
    Button pressed = (Button) ev.getSource();
    System.out.println("Pressed: " + pressed.getLabel());
}


Eine weitere M�glichkeit bietet die Methode

    Button#setActionCommand(String command)

Hiermit kann ein dem Knopf ein beliebiger String zugewiesen. Dieser kann
mit

    ActionEvent#getActionCommand()

wieder abgefragt werden. Dabei wird immer der String zur�ckgegeben, der
dem Event ausl�senden Knopf zugewiesen wurde.

Ein Beispiel:

Button knopf1 = new Button("Max");
knopf1.setActionKommand("schlimmer bub 1");
Button knopf2 = new Button("Moritz");
knopf2.setActionKommand("schlimmer bub 2");

public void actionPerformed(ActionEvent ev) {
    String c = ev.getActionCommand();
    if (c.equals("schlimmer bub 2"))
        System.out.println("Moritz wurde aktiviert");
}




3.5.2. Kann ich ein Fenster (Frame/JFrame) maximieren?
       Autor: Karsten Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Antwort: Jein.

Bis zum J2SDK 1.3 (einschlie�lich) gibt es keine M�glichkeit, ein
Fenster zu maximieren. Es gibt nur verschiedene Workarounds, um ein
Fenster m�glichst fl�chendeckend auf dem Desktop darzustellen (s.u.)

Ab dem J2SDK1.4 gibt es die Methode setExtendedState(int state) aus
der Klasse java.awt.Frame, mit der das Fenster *vielleicht*
maximiert wird. Ob das m�glich ist, kann mittels
isFrameStateSupported(int state) aus dem Toolkit ermittelt werden,
denn nicht jede Plattform unterst�tzt solche maximierten Fenster.

F�r Anwendungen, die mittels einer J2SDK-Version bis 1.3 erstellt werden
sollen, gibt es nur Workarounds, da es eine "Maximieren"-Funktion
nicht gibt. F�r den Windows-Benutzer mag das merkw�rdig sein, f�r
den Unix-Benutzer ist der Gedanke merkw�rdig, dass die tats�chliche
Bildschirmgr�sse etwas mit der Desktopgr��e zu tun haben sollte.

Lange Rede, kurzer Code:
um ein Fenster m�glichst gro� zu machen, nehme man
  setSize(getToolkit().getScreenSize());

Hierdurch wird das darzustellende Fenster vielleicht auf die Gr��e
der aktuellen Bildschirmaufl�sung gesetzt. Ohne Ber�cksichtigung
evtl.  darzustellender Men�- und/oder Taskleisten.

Falls auf der Laufzeitplattform ein �ffnendes Programmfenster von
einem Fenstermanager platziert wird, hat die setSize(Dimension)-Methode
m�glicherweise keine Auswirkung auf das Fenster. Der Programmierer sollte
sich also nicht darauf verlassen, dass sein Fenster so dargestellt wird,
wie er es programmiert hat!

Eine weitere M�glichkeit, ein Fenster evtl. zu maximieren besteht
darin, die Klasse java.awt.Robot (seit J2SDK 1.3) zu benutzen, um die
Maximieren-Schaltfl�che programmgesteuert anklicken zu lassen.
Hinweise zur Benutzung dieser Klasse finden sich im JDC Tech Tip
vom 11. Juli 2000
<URL:http://developer.java.sun.com/developer/TechTips/2000/tt0711.html)

Wegen dieser ganzen Unw�gbarkeiten ist es oft eine Alternative, statt
das Fenster zu maximieren, es einfach Wiederherzustellen und die Gr��e
und Position des Fensters von einem vorherigen Programmlauf zu benutzen.
Hierbei sollte jedoch darauf geachtet werden, dass die Geometrie eines
maximierten Fensters *nicht* durch ein normales Fenster nachgebildet
wird, weil der Anwender sonst dadurch verwirrt wird, dass das Fenster
maximiert aussieht, es aber in Wirklichkeit nicht ist!


3.5.3. Wie tausche ich die Kaffeetasse im blauen Balken aus?
       Autor: Karsten Schulz, Roger Schuster, Christian Wederhake
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit java.awt.Frame#setIconImage(java.awt.Image).

Beispiel:

    ImageIcon icon = new ImageIcon("meinBildchen.gif");
    setIconImage(icon.getImage());


3.6. [SWING] - Frage bez�glich Swing.
-------------------------------------

3.6.1. Wie mache ich globale Font-�nderung f�r meine Komponenten?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* UIManager.put("component.font", new FontUIResource(...));


3.6.2. Wie kann ich bei der Eingabe in ein JTextField die Anzahl
       der eingebbaren Zeichen beschr�nken?
       Autor: Alexander Elsholz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wenn ein JTextField benutzt wird sollte man ein
benutzerdefiniertes Document implementieren. F�r
AWT-Textfelder funktioniert es mit einigen Anpassungen
auch �ber das Interface KeyListener.


import javax.swing.text.PlainDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;

/**
 * Diese Klasse ist ein Dokument f�r Textfelder, welches die Eingabe auf
 * x Zeichen begrenzt.
 *
 * Die Zuweisung geschieht �ber
 * JTextfield.setDocument(new Validation(int anzahl));
 */
public class Validation extends PlainDocument{
    private int limit;

     /**
      * Konstruktor f�r das Validationdokument
      * @param int limit: maximale Anzahl der einzugebenen Zeichen
      */
     public Validation(int newLimit){
         super();
         if (limit < 0){
             limit = 0;
         } else {
             limit = newLimit;
         }
     }

    /**
     * Funktion �berschreibt die Methode insertString von PlainDocument
     * @param int offset: Position
     * @param String str: der String
     * @param AttributeSet attr: Attributset
     */
    public void insertString (int offset, String str, AttributeSet attr)
            throws BadLocationException {
        if (str == null) return;

        if ((getLength() + str.length()) <= limit){
            super.insertString(offset, str, attr);
        }
     }
}

Die hier aufgezeigte L�sung zur Begrenzung von Textfeldern kann auch
verwendet werden, wenn unerw�nschte Zeichen in einem Textfeld nicht
eingegeben werden d�rfen.


3.6.3. Wie setze ich den Cursor an den Anfang der JTextArea?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* textarea.setCaretPosition(0);


3.6.4. Wie scrolle ich an das Ende der JTextArea?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hierzu existieren mehrere M�glichkeiten:

* textarea.setCaretPosition(textarea.getDocument().getLength());

* try{

  textarea.scrollRectToVisible(textarea.modelToView(
                           textarea.getDocument().getLength()));

  } catch (BadLocationException be) {
           be.toString();
}

* (Geht auch, weniger sch�n): mit getText().length();


Scrolling wrappen in SwingUtilities.invokeLater(), bspw:

SwingUtilities.invokeLater(new Runnable() {

   public void run() {

   // scrolling code

  }
};


3.6.5. Wie bekomme ich es hin, das der Benutzer in meiner JTable
       keine Eingaben t�tigen kann?
       Autor: Alexander Elsholz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das funktioniert �ber das Tabellenmodell deiner JTable:

import javax.swing.table.DefaultTableModel

/**
 * Diese Klasse repr�sentiert das Datenmodell f�r eine oder mehrere
 * Tabellen
 *
 * Die Zuweisung geschieht �ber JTable.setModel(new YourTableModel()));
 */
public class YourTableModel extends DefaultTableModel {

    /**
     * aus der API: Returns true if the cell at rowIndex and columnIndex
     * is editable. Otherwise, setValueAt on the cell will not change the
     * value of that cell.
     */
    public boolean isCellEditable(int row, int column) {
        return false;
    }
}

Dieses Bespiel verhindert das Editieren von zellen in allen Zellen der
Tabelle, durch Auswerten der Parameter k�nn aber auch einzelne Spalte,
Zeilen oder Zellen gesperrt werden.


3.6.6. Wie bekomme ich eine horizontale ScrollBar bei JTable?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);


3.6.7. Wie scrolle ich ans Ende von JTable?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* table.scrollRectToVisible(table.getCellRect(
                            table.getRowCount()-1,-1,true));


3.6.8. Wie verhindere ich ein reordering der Spalten bei JTable?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* table.getTableHeader().setReorderingAllowed(false);


3.6.9. Wie verhindere ich ein Resizen der Spalten bei JTable?
       Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* table.getTableHeader().setResizingAllowed(false);


3.6.10. Wie �ndere ich die Hintergrundfarbe von JScrollPane?
        Autor: Linda Radecke
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das geht mit:

* scrollpane.getViewport().setBackground(new Color(....));


3.6.11. Wie kann ich ein JLabel dazu bringen, seinen Hintergrund
        zu f�llen?
        Autor: Gerhard Bloch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
JLabel zeichnet (wie die meisten Swing-Komponenten) seinen Hintergrund
nicht, wenn es nicht "opaque" ist (obwohl dies unterschiedliche Dinge
sind).

Loesung:
Fuer *undurchsichtige* Hintergrundfarben funktioniert folgendes:

JLabel l = new JLabel("Text");
l.setOpaque(true);
l.setBackground(Color.red);


Diese Loesung funktioniert auch fuer transparente Hintergrundfarben:

public class JLabelWithBackground extends JLabel {
    public JLabelWithBackground(String title) {
        super(title);
    }

    public void paintComponent(Graphics g) {
        if (!isOpaque()) {
            Rectangle vr = getVisibleRect();
            g.setColor(getBackground());
            g.fillRect(vr.x, vr.y, vr.width, vr.height);
        }
        super.paintComponent(g);
    }
}

JLabel l = new JLabelWithBackground("Text");
l.setBackground(new Color(255, 0, 0, 128));


3.6.12. Warum reagiert meine GUI nicht, w�hrend eine l�ngere 
        Berechnung ausgef�hrt wird?
        Autor: Tobias Vogele
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Im Prinzip funktioniert das folgenderma�en:
Es gibt bei Swing einen besonderen Thread: den Event Dispatch Thread
(EDT). Wenn immer Du ein Event von Deiner GUI bekommst, z.B. ein
ActionEvent, dann befindest Du Dich im Event Dispatch Thread (EDT). In
diesem werden aber nicht nur Events, die der Benutzer z.B. durch
Mausklicks verursacht hat, erzeugt, sondern in diesem Thread wird auch
die Anforderung f�r das Neuzeichnen verarbeitet

Das Problem ist nun: Wenn Du im EDT (z.B. bei der Behandlung eines
GUI-Events) eine l�ngere Berechnung oder was auch immer ausf�hrst, dann
kann in diesem Thread nat�rlich so lange nichts anderes passieren, also
kann sich auch die GUI auch nicht mehr neu zeichnen, obwohl es
vielleicht n�tig w�re. Das bedeutet auch, da� �nderungen, die w�hrend
der Berechnung an der GUI vorgenommen werden, nicht sichtbar sind,
bevor die Berechnung nicht beendet ist, da erst dann die GUI neu
gezeichnet werden kann.

Die L�sung ist daher: Du mu�t Deine Berechnung in einem anderen Thread
ausf�hren.

Das weitere Problem dabei: Wenn diese Berechnung �nderungen an der GUI
veranla�t, dann m�ssen diese wieder im EDT ausgef�hrt werden, da Swing
im allgemeinen nicht thread-safe ist.

Wie geht beides: 
Einen neuen Thread starten:
  new Thread(calculation, "CalculationThread").start();
Etwas im EDT ausf�hren:
  SwingUtilites.invokeLater(guiChanges);


Weitere Informationen dazu und alternative L�sungsans�tze:

1) Artikel-Serie "Threads and Swing"
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

2) Foxtrott, ein Rahmenwerk um anders zu schreiben, was der 
Swing-Worker aus 1) kann:
http://foxtrot.sourceforge.net/

3) Spin, eine weitere Threading-Bibliothek f�r Swing
http://spin.sourceforge.net/


Hier ein konkretes, lauff�higes Beispiel: 
W�hrend einer l�ngeren Berechnung soll eine ProgressBar den 
Fortschritt anzeigen.

import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;

public class Beispiel implements ActionListener{

        JProgressBar progressBar = new JProgressBar(0, 10);

        public void actionPerformed(ActionEvent e) {
                Runnable calculation = new Runnable() {
                        public void run() {
                                bigCalculation();
                        }
                };
                // Neuen Thread starten:
                new Thread(calculation, "CalculationThread").start();
        }

        /**
         * Hier ist die gro�e Berechnung, die gleichzeitig die 
         * ProgressBar updaten soll.
         */
        private void bigCalculation() {
                for (int i = 0; i <= 10; i++) {
                        calculateNextStep();
                        setProgress(i);
                }
        }
        

        void calculateNextStep() {
                try {
                        Thread.sleep(500);
                } catch (InterruptedException e) {
                }
        }


        void setProgress(final int newProgress) {
                // Wert der ProgressBar im EDT �ndern: 
                SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                                progressBar.setValue(newProgress);
                        }
                });
        }
        
        public static void main(String[] args) {
                Beispiel bsp = new Beispiel();
                JButton button = new JButton("Rechne...");
                button.addActionListener(bsp);
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new FlowLayout());
                frame.getContentPane().add(button);
                frame.getContentPane().add(bsp.progressBar);
                frame.pack();
                frame.setVisible(true);
        }
}


Es sei hier auch noch auf das Tutorial von Sun zur Verwendung von
JProgessBars hingewiesen, da dort anders vorgegangen wird als hier:
http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html

Dort wird die JProgressBar �ber einen Timer angesteuert und nicht �ber
einen expliziten Aufruf von setProgress. Allerdings war es ja hier
gerade die Absicht, zu zeigen, wie man aus einem extra Thread heraus
GUI-Methoden aufruft.


3.7. [APPLET] - Frage zu Java-Applets und ihre Zusammenarbeit
                mit Browsern.
--------------------------------------------------------------

3.7.1. Welche JDK-Version sollte ich f�r Applets verwenden, die
       m�glichst allgemein lauff�hig sein sollen?
       Autor: Stefan Menzel
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Am besten nicht �ber 1.1.8.


3.7.2. Wie bekomme ich den Internet Explorer dazu, das Plugin
       anstelle der integrierten JVM zu benutzen.
       Autor: Stefan Menzel, Aljoscha Rittner, Joachim Sauer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Indem auf der aufrufenden Webseite nicht das <APPLET>, sondern das
<OBJECT>-Tag verwendet wird. Es gibt auf
<URL:http://java.sun.com/products/plugin/1.3/docs/html_converter.html>
einen automatischen Konverter einer Seite zur Benutzung des Plugins.

Mit 1.4 kann auch das APPLET-Tag zusammen mit dem Plugin verwendet
werden. Dazu findet man n�here Informationenen unter:

<URL:http://java.sun.com/j2se/1.4/docs/guide/plugin/developer_guide/
html_converter_more.html>

Anmerkung: Mit 1.4 kann auch das APPLET-Tag zusammen mit dem Plugin
verwendet werden. Aber alle, die f�r JDKs gr��er 1.2 coden sollten
ohnehin OBJECT verwenden, da sie mit APPLET (auch mit den neuen Plugins)
auf Browser sto�en k�nnen, die zwar glauben es darstellen zu k�nnen,
dann aber kl�glich scheitern. Wer f�r 1.1 programmiert sollte sich wohl
wirklich noch das APPLET-Tag �berlegen.


3.7.3. Was d�rfen unsignierte Applets nicht aus Sicherheitsgr�nden?
       Autor: Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Applets wurden generell stark in ihren Rechten eingeschr�nkt.
Die genauen Einschr�nkungen sind von der Virtuellen Maschine,
also Browser / Plugin oder Appletviewer abh�ngig.

Einem signierten Applet kann man explizit mehr Rechte geben
als das normalerweise der Fall ist. Auch gibt es Unterschiede,
ob das Applet von remote oder vom Filesystem geladen wurde.

Ein von remote geladenes Applet darf in der Regel nicht:

* auf das lokale Filesystem zugreifen
* auf die (System-)Zwischenablage zugreifen
* Socketverbindungen zum lokalen Host aufbauen.
* Socketverbindungen zu dritt-Hosts aufbauen.
* System-properties �ndern/setzen
* System-properties lesen ausser:
  java.version, java.vendor,java.vendor.url, java.class.version
  os.name, os.arch, os.version,
  file.separator, path.separator, line.separator
* lokal Programme starten
* lokale Bibliotheken laden
* System.exit(int) aufrufen
* Fenster ohne Warnung �ffnen

Signieren heisst, das Applet mit einer verschl�sselten Unterschrift
(Signatur) zu versehen, um diesen mehr Rechte zuzuweisen.

Signieren bedarf einer "vertrauensw�rdigen" Person bzw. Institution,
unterschiedlich, je ob das Applet nur in einem Intra- oder im gesamten
Internet betrieben werden soll.

Der Prozess des Signieren-Lassens wurde leider noch zus�tzlich
dadurch erschwert, dass man jede Signatur praktisch f�r jede
Browser-VM extra durchf�hren mus.

Genaueres siehe:
  <URL:http://java.sun.com/sfaq>
(Dort auch b�se Testapplets.)

Zur Java-Security und Codesignierung allgemein siehe:
  <URL:http://www.securingjava.com/toc.html>
  <URL:http://home.iSTAR.ca/~neutron/java.html>

und spezieller:

  <URL:http://www.abim.net/jsw/index.htm>
  <URL:http://www.iw.uni-hannover.de/~ruemper/>
  <URL:http://www.suitable.com/Doc_CodeSigning.shtml>
  <URL:http://developer.netscape.com/docs/manuals/signedobj/signtool/
  index.htm> (umgebrochen)
  <URL:http://java.sun.com/products/plugin/1.2/docs/nsobjsigning.html>
  <URL:http://developer.java.sun.com/developer/onlineTraining/
  Programming/JDCBook/signed.html> (umgebrochen)


3.8. [SERVER] - Frage zu Servlets und anderen Server-
                Implementierungen in Java.
-----------------------------------------------------



3.9. [NONCORE] - Fragen zu Klassen/Packages, die �ber den Kern der
                 Sprache  hinausgehen, also Java3D etc.
------------------------------------------------------------------



3.10. [OOP] - Frage bez�glich OOP-Konzepten und Patterns in Java.
----------------------------------------------------------------

3.10.1. Was bedeutet Vererbung im OO-Kontext?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vererbung ist in Java, und nat�rlich auch in anderen Programmiersprachen,
nur eine M�glichkeit, um das konkrete Problem in den Computer zu
�bertragen. Das Prinzip der Vererbung ist dann anwendbar, wenn zwei
Objekte in einer ist-ein oder ist eine Art von Beziehung zueinander
stehen. Eine abgeleitete Klasse ist ein Subtyp der zugeh�rigen
Oberklasse, besitzt also deren Eigenschaften (Daten & Methoden) und
erweitert diese bei Bedarf um neue. LKW und PKW sind zum Beispiel
Subtypen der Oberklasse Automobil, wobei beim LKW zum Beispiel die
maximal zul�ssige Anh�ngerlast oder die Achsenanzahl hinzukommt.

Wendet man das Prinzip der Vererbung an, so gilt das sogenannte
Liskov'sche Substitutionsprinzip:

Objekte der abgeleiteten Klasse k�nnen stets an die Stelle von Objekten
der Oberklasse treten.


3.10.2. Was bedeutet Aggregation im OO-Kontext?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das Prinzip der Aggregation besagt, da� ein Objekt aus mehreren Teilen
(=Objekten) besteht, die wiederrum aus Teilen bestehen k�nnen usw.
Die Klasse Computer k�nnte z.B. aus den Klassen Speicher, Festplatte
etc. bestehen. In einem Pseudo-Java-Code etwa so formuliert:

public class Computer {
    private Speicher rom;
    private Speicher ram;
    private Speicher festPlatte;

    (...)
}


3.10.3. Was bedeutet Assoziation im OO-Kontext?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mit der Assoziation wird die Verbindung des Objektes zu einem oder
mehreren anderen Objekten beschrieben. Assoziationen k�nnen kurzfristig
sein, zum Beispiel dann, wenn ein anderes Objekt an das aktuelle Objekt
als Parameter der Objektmethode �bergeben wird. Sie k�nnen aber auch
langfristig sein, wenn das Objekt Referenzen auf die assoziierten
Objekte speichert (Registrierung).


3.10.4. Was bedeutet Benutzung im OO-Kontext?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das aktuelle Objekt benutzt eines oder mehrere andere Objekte um die
anstehende Aufgabe erf�llen zu k�nnen. Das Objekt Backofen benutzt zum
Beispiel das Objekt Thermostat, um die Aufgabe backen zu erf�llen, damit
der Inhalt des Backofens nicht verkohlt.

Es mu� angemerkt werden, da� man h�ufig aus dem Programmcode keine
direkte Entscheidung treffen kann, ob Aggregation, Assoziation oder
Benutzung vorliegt. Diese drei Beziehungen sind prinzipiell
Designprinzipien, die in der sp�teren Implementierungsphase, zum
Beispiel in Java, in relativ �hnliche oder sogar identische Konstrukte
umgesetzt werden. Es ist deshalb wichtig, da� man das jeweils zugrunde
gelegte Prinzip dokumentiert, damit die Funktionsweise besser und
einfacher nachvollzogen werden kann.


3.10.5. Worin liegen die Unterschiede zwischen abstrakten Klassen
        und Interfaces?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Java f�gt dem schon von C++ her bekannten Konzept der abstrakten Klasse
noch ein weiteres, aus der Sprache Objective-C entliehenes Feature hinzu:
Interfaces. Ein Interface ist zuersteinmal nichts anderes als eine
Auflistung von Methoden. Eine Klasse implementiert ein Interface, wenn
sie alle in der Interface-Deklaration angegebenen Methoden besitzt.
Wird mindestens eine der Methoden des Interfaces nicht implementiert, so
wird die Klasse zu einer abstrakten Klasse. Mit dem Interface-Prinzip
lassen sich in Java einfach Benutzt-Beziehungen modellieren. Eine Klasse
benutzt eine andere Klasse in dem Sinn, da� es ganz spezielle Methoden
dieser Klasse verwendet, um seine eigene Funktionalit�t zu realisieren -
auf Daten der Hilfsklasse wird ja wegen dem Prinzip der Datenkapselung
nicht direkt zugegriffen. Um ein Objekt zu benutzen, ist es nur wichtig,
da� dieses Objekt die gew�nschten Funktionen auch besitzt. Man definiert
sich daher ein Interface, welches die ben�tigten Funktionen auflistet.
Alle Objekte, die diese Funktionen ben�tigen, sprich, die dieses
Interface verlangen, k�nnen nun all die Klassen verwenden, die dieses
Interface implementieren. Im Sinne eines guten Klassendesigns ist es
daher wichtig, solche Benutzt-Beziehungen zu lokalisieren, um die
Klassen flexibler zu machen und unn�tigerweise angewendete Vererbung zu
eliminieren. Abstrakte Klassen sind im Gegensatz dazu Modellierungen
des Ist ein-Prinzips und unterscheiden sich in dieser Hinsicht von
Interfaces.


3.10.6. Was ist eine anonyme innere Klasse?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Eine anonyme innere Klasse tr�gt keinen Namen und wird vor allem bei der
GUI-Programmierung f�r Adapterklassen verwendet. Wird eine solche Klasse
in ein Class-File �bersetzt, so werden alle anonymen Klassen, die in der
umgebenden Klasse definiert wurden, von Null beginnend durhnummeriert.

    Testklasse$0.class

ist also das Class-File der ersten in der Klasse  Testklasse
auftauchenden anonymen inneren Klasse.


3.10.7. Was ist ein immutable Objekt?
        Autor: Gerhard Bloch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ein immutable (unveraenderliches) Objekt ist ein Objekt, das nach seiner
Instanzierung nicht mehr veraendert werden kann. Bekannte Beispiele
hierfuer sind saemtliche Wrapper-Klassen (Integer, Boolean,... ) sowie
die Klasse String.

Dieses Design-Pattern bietet folgende Vorteile:
+ Instanzen koennen gefahrlos mehrfach referenziert werden
+ keine Synchronisation noetig
+ sehr gut geeignet als Schluessel fuer HashMap

Immutable Objekte muessen folgende Forderungen erfuellen:
+ alle Attribute sind final
+ alle nicht selbst immutable Attribute sind zusaetzlich private
+ kein Schreibzugriff auf Attribute moeglich
+ direkter Lesezugriff ist nur auf selbst immutable Attribute erlaubt
+ im Konstruktor uebergebene mutable Objekte muessen geklont(*) werden

(*) Klonen ist hier in der Bedeutung "tief genug kopieren" gemeint: Es
muessen rekursiv alle mutable Attribute kopiert werden. Dies hoert sich
komplizierter an, als es in der Praxis ist, da die verwendeten Objekte
i.d.R. nicht verschachtelt sind, reicht meist eine flache Kopie aus.


Beispiel:

public class MyImmutable {
    public  final int i;
    private final String s;
    private final int[] a;
    private final Point p;

    public MyImmutable(int i, String s, int[] a, Point p) {
        this.i = i;                  // primitiver Typ ist immutable
        this.s = s;                  // String ist immutable
        this.a = new int[a.length];  // Arrays sind mutable!
        System.arraycopy(a, 0, this.a, 0, a.length);
        this.p = new Point(p);       // Point ist mutable!
    }

    public String getS() {
        return s;
    }

    // Array ist mutable, also Klon zurueckgeben
    public int[] getA() {
        return (int[]) a.clone();
    }

    // alternativ: Elementzugriff, die int-Elemente sind immutable
    public int getAAt(int pos) {
        return a[pos];
    }

    // Point ist mutable, also Klon zurueckgeben
    public Point getP() {
        return new Point(p);
    }
}


Zusaetzlich ist folgendes zu beachten:
Subklassen von Immutables muessen selbst nicht immutable sein und
koennen im schlimmsten Fall sogar das Konzept unterlaufen!

Beispiel:

public class AntiImmutable extends MyImmutable {
    public String s;

    public AntiImmutable(int i, String s, int[] a, Point p) {
        super(i, "", a, p);
        this.s = s;
    }

    public String getS() {
        return s;
    }
}

MyImmutable mi = new AntiImmutable(0, "A", anIntArray, new Point(0, 0));
((AntiImmutable)mi).s = "B";
System.out.println(mi.getS());

--> Ergibt "B"!!!

Daher ist es meist angebracht, Immutables final zu deklarieren! Zudem
sollte man Attribute, die zwar immutable, aber nicht final sind, wie
Mutables behandeln (also im Konstruktor bzw. bei der Rueckgabe klonen).


3.11. [JDK] - Frage zu virtuelle Maschinen, alles �ber JDKs und deren
              Installation und Verwendung.
---------------------------------------------------------------------

3.11.1. Was ist ein Java Development Kit (JDK)
        Autor: Hubert Partl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das JDK ist eine Software, die f�r die Erstellung, �bersetzung und
Ausf�hrung von Java-Programmen notwendig ist; enth�lt unter anderem den
Java-Compiler, das Java Runtime Environment JRE und diverse
Hilfsprogramme. Der Name bedeutet �bersetzt Java-Entwicklungs-Werkzeug.


3.11.2. Was ist ein Java Runtime Environment (JRE)
        Autor: Hubert Partl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das JRE ist eine Software, die f�r die Ausf�hrung von Java-Programmen
notwendig ist; enth�lt unter anderem die Java Virtual Machine JVM und
die Klassenbibliothek. Der Name bedeutet �bersetzt Java-Laufzeit-
Umgebung.


3.11.3. Was ist eine Java Virtual Machine (JVM)
        Autor: Hubert Partl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Die JVM ist eine die Software, die notwendig ist, um ein Java-
Bin�rprogramm (Bytecode) auf einem Computer auszuf�hren. Der Name
bedeutet virtuelle Java-Maschine und kommt daher, dass der Computer,
der direkt nur Windows- oder Macintosh- oder Unix-Bin�rprogramme
ausf�hren kann, mit Hilfe der JVM so wirkt, als ob er Java-Bytecode
ausf�hren k�nnte, also als ob er eine Java-Maschine w�re.


3.11.4. Wie konfiguriere ich JDK1.3/1.4 unter Linux oder Unix?
        Autor: Martin Erren, Michael Paap
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Frage:

Bei meinem Linux ist per default kaffe (jdk1.1.8) eingestellt, obwohl
ich das Sun jdk installiert habe. Wie kann ich 1.3 unter Linux benutzen?

Antwort:

Die default-Einstellungen sind gut f�r jene, die nur GNU-Lizenzen
akzeptieren, aber schlecht f�r solche, die ernsthaft in Java entwickln
oder anspruchsvolle Java-Programme benutzen wollen.

I. SuSE Linux

SuSE macht die Umstellung auf das aktuelle Sun-jdk wenigstens einfach.
Sie muss jedoch per Hand erfolgen.

Ein normaler Benutzer hat /usr/lib/java/bin im $PATH.
(Unter root braucht/soll Java nicht gestartet werden)
/usr/lib/java ist ein symbolic link auf /usr/lib/jdk1.1.8,
eine Variante vom jdk 1.1.8 namens kaffe.

Man vergewissere sich dessen mit

# file /usr/lib/java

Falls tats�chlich ein symbolic link, kann man diesen getrost
(unter root) mit

# rm /usr/lib/java

l�schen und mit

# ln -s /usr/java/jdk1.3.1_01 /usr/lib/java

auf das Sun jdk neu verlinken. Weiterhin sollte man in /etc/rc.config
die Variable CREATE_JAVALINK auf "no" setzen, sonst setzt SuSEConfig den
Link wieder in den Urzustand, wenn es das n�chste Mal
l�uft.

Diese Angaben gelten f�r SuSE 7.3 und k�nnen pro
Distributions-Version geringf�gig von der beschriebenen
Struktur abweichen.

(Falls Dir symbolic links, file, rm, $PATH nichts sagen,
solltest Du Dir eine kleine Einf�hrung in UN*X besorgen,
zum Beispiel [...])


II. Unix/Linux Allgemein

Da andere Linux Distributionen nicht so verbreitet sind wie SuSE,
k�nnen hier kaum alle Originalkonfigurationen durchgegangen werden.

Bei allen UN*X Varianten kann man aber immer so analysieren:

* Mit "java -version" die installierte JRE �berpr�fen.
* Mit "type java" erkennen ob "java" ein alias, oder eine ausf�hrbare
  Datei ist, bzw. wo sie im Filesystem liegt.
* Mit "file .../java" erkennen, ob es sich um ein script oder eine
  binary handelt.

Und so zu einem installierten Sun-JDK umlenken ($JAVA_HOME sei das
installierte Sun JDK):

* Den $PATH �ndern, Eintrag auf $JAVA_HOME/bin *vor* der Original-
  Binary
* "alias" setzen (hat immer Vorrang).
* Etwaige links umbiegen wie oben beschrieben.

Die Variable $JAVA_HOME sollte man ebenfalls setzen, da einige
Programme so das installierte JDK finden (z.B. Tomcat).


3.11.5. Wie installiere und konfiguriere ich das jdk unter
        Windows 9x/Me/NT/2000 richtig?
        Autor: Wolfgang Schirmer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Als Referenz-jdk nehmen wir das jdk1.3.1 !
Nach dem Download des jdk 1.3.1 wird die Installationsroutine �ber den
klick auf die jdk1_3_1-win.exe gestartet. Nach der Begr�ssung und den
Auszug aus den Lizenzbedingungen erfolgt die Auswahl des Installations-
verzeichnisses. Standardm�ssig wird das Verzeichnis C:\jdk1.3.1
vorgeschlagen. Dies kann aber �ber Browse ge�ndert werden. Nach der
Festlegung des Installationsumfanges werden die Dateien auf die
Festplatte kopiert.

Durch die Eingabe des Kommandos:

java -version

in der DOS-Box kann festgestellt werden welche Version auf dem System
installiert wurde. F�r dieses Beispiel sollte folgende Nachricht als
Reaktion auf das Kommando erscheinen:

    java version "1.3.1"

Als n�chstes sind die PATH-Einstellungen zu �berpr�fen. Hierbei
ist es wichtig zu wissen, dass die PATH-Anweisung die Pfade festlegt,
in denen das Betriebssystem nach Programmen sucht.

Unter Windows 9x/Me wird die Pfadeinstellung in der autoexec.bat
durchgef�hrt. Hier sollte die PATH-Zeile folgendermassen aussehen:

    PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\jdk1.3.1\bin

Nach dieser �nderung in der autoexec.bat muss das System neu
gestartet werden, damit die �nderungen auch wirksam werden.

Unter WindowsNT/2000 ist die Pfadeinstellung in der
Systemsteuerung|System|Umgebung innerhalb der Systemvariablen
vorzunehmen. Hier ist der Eintrag in der Variablen PATH durch die
Zuweisung:

    ;C:\jdk1.3.1\bin

zu erg�nzen. Die �nderungen werden erst in den nach der �nderung
ge�ffneten DOS-Box wirksam. Achtung! Um unter WinNT/2000 diese
Einstellungen vornehmen zu k�nnen muss man die Administrator-
Berechtigung besitzen.


3.12. [TOOLS] - Frage zu einem Java-Zusatz-Tool, zum Beispiel IDEs,
                Build-Tools, Profiler, etc.
-------------------------------------------------------------------

3.12.1. Welche IDE muss ich verwenden?
        Autor: Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<URL:http://groups.google.com/groups?q=beste+%2B+IDE+%2B+Java
++-emacs+-vi+-vim+-notepad+group%3Ade.comp.lang.java&hl=de&btnG
=Google-Suche>

BTW: Der Link muss aus den 3 Zeilen zusammengesetzt werden !

Bietet eigentlich jederzeit einen guten �berblick.


3.12.2. Wie kann man eine Java-Anwendung in eine EXE-Datei umwandeln?
        Autor: Marco Schmidt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ein nativer Compiler ist in der Lage, Quelltext oder Bytecode in eine
native Anwendung (statt wie �blich bei Java in Bytecode, also
.class-Dateien) umzuwandeln, etwa eine EXE-Datei unter Windows.

Auf

<URL:http://www.geocities.com/marcoschmidt.geo/java-native-compilers.html
#products>

sind u. a. auch einige native Compiler und weiterf�hrende Links zum
Thema "native compilation" aufgelistet.

BTW: Der Link muss aus 2 Zeilen zusammengesetzt werden !

Bei der Verwendung gibt es allerdings ein paar Punkte zu beachten.

* Gute native Compiler sind recht teuer und somit nur im
professionellen Umfeld sinnvoll einsetzbar. Der freie native Compiler
gcj unterst�tzt z. B. nur Java 1.1, und auch das nur teilweise (kein
AWT etc.).

* Obwohl das vom nativen Compiler erzeugte Programm aus nativem Code
besteht, mu� oft trotzdem noch ein Java Runtime Environment
installiert werden, so da� der Vorteil der einfachen Verteilung des
Programms wegf�llt - der Benutzer k�nnte genauso gut direkt das JRE
installieren und die Bytecode-Version der Anwendung starten.

* Der gro�e Geschwindigkeitsvorteil durch nativen Code existiert
heutzutage nicht mehr, da moderne JVMs durch Just-in-time-Compiler in
den meisten F�llen sehr nah an nativen Code herankommen. In
Einzelf�llen mag es aber durchaus Vorteile bei nativem Code geben.

* Da es native Compiler nicht f�r all diejenigen Plattformen gibt, f�r
die auch JREs existieren, schr�nkt man die Anzahl potentieller Nutzer
ein, wenn man auf nativen Code besteht. Allerdings d�rften mit nativen
Compilern f�r Windows und ein paar der verbreiteteren Unix-Varianten
absolut gesehen der gr��te Teil aller Computerbenutzer abgedeckt sein.

* Wer nativen Code verwendet, mu� eventuell mehrere Versionen des
Programms f�r verschiedene Plattformen pflegen. Durch die Verwendung
von Bytecode (.class-Dateien) hat man eine Version, die �berall
ausgef�hrt werden kann ("write once, run anywhere").

Zum Schlu� noch ein paar Vorteile durch die Verwendung eines nativen
Compilers.

* Native Programme starten meist schneller - dies ist f�r lang
laufende Server-Anwendungen nicht so wichtig, f�r h�ufig aufgerufene
Kommandozeilenprogramme allerdings schon eher.

* Es ist schwerer, nativen Code als Bytecode zu dekompilieren (also
wieder den Quelltext zu erhalten). Wer also Reverse-engineering seines
Programms f�rchtet, hat bei Bytecode mehr Anla� zur Sorge.

* Einige native Compiler erm�glichen es, da� gleichzeitig laufende
Instanzen der erzeugten Programme sich gewisse Ressourcen teilen und
so weniger Arbeitsspeicher verbrauchen. Aktuelle JVMs laufen stets
v�llig unabh�ngig voneinander ab (dies wird sich vielleicht nach Java
1.4 �ndern).  Man kann mit nativen Anwendungen also mehr Instanzen
eines Programms auf demselben System laufen lassen.

Native Compiler haben in einigen Nischen also durchaus
Daseinsberechtigung. Allerdings sollte, wer sich um einfache
Verteilung seines Programms Gedanken macht, eine der folgenden
M�glichkeiten in Betracht ziehen:

* Suns Java Webstart <URL:http://java.sun.com/products/javawebstart/>

* Ausf�hrbare JAR-Dateien, die sich mit einem Doppelklick auf das
entsprechende Icon starten lassen
<URL:http://java.sun.com/products/jdk/1.2/docs/guide/extensions/
spec.html#executable>

* Einen Installer wie InstallAnywhere <URL:http://www.zerog.com/>,
JExpress <URL:http://www.denova.com/> oder eines der Produkte aus dem
entsprechenden Abschnitt des Open Directory:
<URL:http://dmoz.org/Computers/Programming/Languages/Java/
Development_Tools/Deployment/>


3.13. [MATH] - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.
--------------------------------------------------------------------

3.13.1. Warum rechnet Java falsch?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:

public class Test {
    public static void main(String[] args) {
        float zahl = 0.0F;
        for (int i = 0; i <= 100; i++) {
            System.out.println(zahl);
            zahl += 0.1F;
        }
    }
}

L��t man obiges Programm laufen so ergibt sich folgende Ausgabe:

    0.0
    0.1
    0.2
    0.3
    0.4
    0.5
    0.6
    0.70000005
    0.8000001
    0.9000001
    ...

Scheinbar rechnet Java an einigen Stellen falsch und ist nicht f�hig,
zu einer Zahl den Wert 0.1 korrekt zu addieren. Dies sieht jedoch nur
so aus und ist auch keineswegs typisch f�r die Programmiersprache Java,
sondern ein allgemeines Problem.


Zahlendarstellung im Computer:

Um dies zu verstehen, mu� man sich klar machen, da� ganze Zahlen intern
in Form von Bin�rzahlen und Flie�kommazahlen mit Hilfe von Bin�rbr�chen
dargestellt werden. Nun kann der (nicht gerade seltene) Fall eintreten,
da� sich eine Zahl im Dezimalsystem zwar darstellen l��t, in
Bin�rdarstellung jedoch zu einem unendlichen, nicht abbrechenden, Bruch
wird. F�r die Speicherung einer Zahl steht aber nur ein beschr�nkter
Speicherplatz zur Verf�gung, d.h. die unendliche Bin�rdarstellung wird
nur bis zu einer gewissen Stelle gespeichert. Das Resultat sind
Ungenauigkeiten. Addiert man jetzt solche Zahlen (und 0.1 ist ein
Beispiel f�r so eine Zahl) mehrfach auf, so addieren sich die
unvermeidbaren Ungenauigkeiten immer mehr auf und f�hren zu dem obigen
Verhalten. Dies ist keineswegs charakteristisch f�r Java, sondern auch
in jeder anderen Sprache, die Flie�kommazahlen verwendet,
reproduzierbar. Eine Abmilderung des Problems besteht in einer schlauen
Rundung von Zwischenergebnissen an geeigneten Stellen der Berechnung,
so da� Fehler kompensiert oder zumindest abgeschw�cht werden.


3.13.2. Wie runde ich eine Gleitkommazahl?
        Wie formatiere ich eine Gleitkommazahl?
        Autor: Peter Luschny; Datum: 2004-02-04
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Runden und Formatieren von Gleitkommazahlen

::: 1. Einf�hrung ::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Die Dezimaldarstellung einer Zahl a notieren wir (die Schreibweise a_{i}
bedeutet dabei "a mit einem tiefgestellten Index i")

  a = � a_n a_{n-1} ... a_0 , a_{-1} a_{-2} ... a{-k}

wobei die a_i Ziffern '0','1,','2',...,'9' sind und a_n ungleich 0. Die
rechts vom Vorzeichen stehenden Ziffern hei�en die 'tragenden Stellen'
von a, die rechts vom Komma stehenden Ziffern 'Nachkommastellen' von a.
Jede Zahl a ungleich 0 kann eindeutig in der Form dargestellt werden
a = m * 10^q, wobei 1 <= |m| < 10 und q eine ganze Zahl ist.
Diese Darstellung nennen wir die Gleitkommadarstellung von a.

Beispiel: Die Dezimalzahl 123,45678 hat die Gleitkommadarstellung
1,2345678 * 102. Will man auf 2 /Nachkommastellen/ runden, so m�chte man
die Dezimaldarstellung 123,46 erhalten, will man auf 2 /tragende Stellen/
runden, so m�chte man die Gleitkommadarstellung 1,2 * 102 erhalten.

Die Java-Dokumentation w�hlt noch eine andere Umsetzung. Hier wird die
Zahl aus dem Beispiel als [12345678, 5] dargestellt und allgemein die
Notation [m,s] verwendet, wobei a = m*10^(-s). Hier geht man also von der
Anzahl der Nachkommastellen aus (deren Endlichkeit vorausgesetzt wird),
und es wird von rechts nach links abgez�hlt (man beachte das Minus-
Zeichen des Exponenten). Wir haben also die 3 Darstellungen
        123,45678 = 1,2345678 * 102 = [12345678, 5]

In einem Computer sind nat�rlich nur endlich viele Gleitkommazahlen
darstellbar. In der Mathematik gibt es aber unendlich viele. Will man also
das mathematische Rechnen auf einem Computer 'simulieren', muss man
st�ndig versuchen, trotz dieses Umstandes m�glichst nahe an den 'wahren'
Werten zu bleiben. Dieses Ausw�hlen eines geeigneten Stellvertreters unter
den im Rechner darstellbaren Zahlen ist es, was man, allgemein gesprochen,
'Runden' nennt, und diese Operation ist im Grunde vor und nach jeder
arithmetischen Operationen notwendig, wenn man sicherstellen will, dass
die Gesetze der Mathematik nicht verletzt werden. Die bekanntesten Arten
zum Runden sind: den 'oberen' Nachbarn, den 'unteren' Nachbarn oder die
'n�chstliegende' Zahl im System der darstellbaren Gleitkommazahlen
auszuw�hlen.

Neben dem Runden einer Gleitkommazahl geh�rt zu den Standardaufgaben
sie geeignet zu 'formatieren'. Hier entscheidet man �ber die graphische
Darstellung einer Ziffernfolge beim Anzeigen oder Ausdrucken. Beide
Operationen sind begrifflich unabh�ngig voneinander, werden aber manchmal
verwechselt - dies ist einer der Gr�nden, warum wir sie hier gemeinsam
besprechen. Das Ergebnis einer Rundung ist ein 'double', das Ergebnis
einer Formatierung ein 'String'. F�r beide Operationen stellt die
Java-Bibliothek Klassen zur Verf�gung.

F�r das Rechnen und Runden: 'java.math.BigDecimal',
F�r das Formatieren: 'java.text.DecimalFormat'.

Die folgenden Vorschl�ge setzen eine Version des JDK >= 1.5 voraus.
Wie komplex die Dinge sind, zeigt, dass die Dokumentation von BigDecimal
in der Version 1.5 allein 41 Seiten, die von 'DecimalFormat' 22 Seiten
lang ist. Es wird daher dringend empfohlen, diese Dokumentation zu lesen.

::: 2. Das  Runden  einer  Gleitkommazahl ::::::::::::::::::::::::::::::::

Eine wichtige Art, Gleitkommazahlen in Java in den Griff zu bekommen,
ist es, die Klasse BigDecimal zu verwenden. Dies bietet Vorteile gegen�ber
dem direkten Arbeiten mit 'doubles': In den Feinheiten und Sonderf�llen
der Gleitkomma-Arithmetik sind viele Fu�angeln versteckt, ihnen durch den
Gebrauch der Bibliotheksfunktionen aus dem Weg zu gehen, ist ein guter Rat
nicht nur f�r Anf�nger. Folgende einfache Funktion zum Runden einer
Gleitkommazahl zeigt, wie man dabei vorgehen kann.

//////////////////////////////////////////////////////////////////////////
public static double round
             (double d, int scale, RoundingMode mode, FormatType type)
{
   if (Double.isNaN(d) || Double.isInfinite(d)) return d;
   scale = Math.max(scale,0);  // Verhindert negative scale-Werte
   BigDecimal bd = BigDecimal.valueOf(d);
   if(type == FormatType.exp) {
      BigDecimal bc = new BigDecimal(bd.unscaledValue(),bd.precision()-1);
      return ((bc.setScale(scale, mode)).
               scaleByPowerOfTen(bc.scale()-bd.scale())).doubleValue();
   }
   return (bd.setScale(scale, mode)).doubleValue();
}
//////////////////////////////////////////////////////////////////////////

Kurzbeschreibung der Funktion:
/**
 * @param  d der zu rundende Gleitkommawert.
 * @param  scale die Anzahl der Nachkommastellen, falls type = fix,
 *         die Anzahl der tragenden Stellen - 1,  falls type = exp.
 *         scale sollte >= 0 sein (negative Werte werden auf 0 gesetzt).
 * @param  mode die Rundungsart: einer der Rundungsarten von BigDecimal,
 *         seit 1.5 in java.math.RoundingMode.
 * @param  type ein Element von "enum FormatType {fix, exp}" gibt an,
 *         auf welche Stellen sich die Rundung beziehen soll.
 *         FormatType.exp ('Exponential') steht f�r tragende Stellen,
 *         FormatType.fix ('Fixkomma') steht f�r Nachkommastellen.
 * @return der gerundete Gleitkommawert.
 * <p>Anmerkung: F�r die Werte <tt>double</tt> NaN und &plusmn;Infinity
 * liefert round den Eingabewert unver�ndert zur�ck.
 */

Beispiel: d = -Math.exp(702); for (int scale = 0; scale < 6; scale++)
System.out.println(round(d,scale,RoundingMode.HALF_EVEN,FormatType.exp));

0 -> -7.0E304
1 -> -7.5E304
2 -> -7.49E304
3 -> -7.494E304
4 -> -7.4942E304
5 -> -7.49422E304

Beispiel: d = Math.PI*10000.0; for (int scale = 0; scale < 6; scale++)
System.out.println(round(d,scale,RoundingMode.HALF_EVEN,FormatType.fix));

0 -> 31416.0
1 -> 31415.9
2 -> 31415.93
3 -> 31415.927
4 -> 31415.9265
5 -> 31415.92654

Die Enumeration "enum FormatType {fix, exp};" muss dabei selber definiert
werden. Man beachte auch die Verwendung der Factory-Methode valueOf().
Diese Form ist in der Regel dem Konstruktor 'BigDecimal(double val)'
vorzuziehen. Man lese dazu die Erl�uterungen in der Dokumentation
(Version >= 1.5) von BigDecimal. "This is generally the preferred way to
convert a float or double into a BigDecimal.." Ein einfaches Beispiel
veranschaulicht den Unterschied:

System.out.println(BigDecimal.valueOf(1.005));
System.out.println(new BigDecimal(1.005));

>>>>   1.005
>>>>   1.00499999999999989341858963598497211933135986328125


In Java-Versionen vor 1.5 l��t sich BigDecimal.valueOf(d) simulieren durch
new BigDecimal(Double.toString(d))). Der 'if'-Zweig der Funktion 'round'
ist allerdings in �lteren Versionen nicht (so einfach) zu erhalten: Die
Funktionen precision() und scaleByPowerOfTen() sind erst ab 1.5 im API
enthalten und m�ssten bei �lteren Versionen 'nachgebaut' werden. Entweder
eine nette �bungsaufgabe oder ein guter Grund, auf eine Version >= 1.5
umzusteigen.

BigDecimal stellt 8 M�glichkeiten zur Rundung zur Verf�gung. Will man auf
2 Stellen im 'kaufm�nnischen Sinn' runden, so w�hle man HALF_UP.
Der IEEE-Standard sieht diese Rundung allerdings nicht als den Normalfall
an, und bei numerischen Rechnungen w�hlt man besser HALF_EVEN.
Gebrauchsfertig in handliche Makros gepackt:

public static double roundUpFix2 (double d) {
    return round (d, 2, RoundingMode.HALF_UP, FormatType.fix);
}

public static double roundEvenExp2 (double d) {
   return round (d, 2, RoundingMode.HALF_EVEN, FormatType.exp);
}

::: 3. Das  Formatieren  einer  Gleitkommazahl :::::::::::::::::::::::::::

F�r das Formatieren ist 'java.text.DecimalFormat' das angebotene Werkzeug.
Eine kleine Utility-Funktion 'format' mit einer �hnlichen Aufrufstruktur
wie die Funktion 'round', zeigt hier einen Ansatz:

//////////////////////////////////////////////////////////////////////////
public static String format (double d, int scale, FormatType type)
{
    if (Double.isNaN(d) || Double.isInfinite(d))
        return Double.toString(d);

    scale = Math.max(scale,0); // Verhindert negative scale-Werte
    DecimalFormat df = new DecimalFormat();
    df.setMaximumFractionDigits(scale);
    df.setMinimumFractionDigits(scale);

    if( type == FormatType.exp ) {
        StringBuilder sb = new StringBuilder("0E0");
        if(scale > 0) sb.append(".000000000000000000",0,scale+1);
        df.applyPattern(sb.toString());
    }
    else {
        df.setGroupingUsed(false);
        df.setMinimumIntegerDigits(1);
    }
    return df.format( d );
}
//////////////////////////////////////////////////////////////////////////

 Kurzbeschreibung der Funktion:
 /**
 * @param  d der zu formatierende Gleitkommawert.
 * @param  scale die Anzahl der Nachkommastellen, falls type = fix,
 *         die Anzahl der tragenden Stellen - 1,  falls type = exp.
 *         scale sollte >= 0 sein (negative Werte werden auf 0 gesetzt).
 * @param  type ein Element von "enum FormatType {fix, exp}".
 *         FormatType.exp fordert eine eine wissenschaftliche Exponential-
 *         darstellung an, FormatType.fix fordert ein Fixkommaformat an.
 * @return eine Zeichenkette, die den Gleitkommawert darstellt und
           entsprechend den gew�nschten Parametern formatiert ist.
 * <p>Anmerkung: F�r die Werte <tt>double</tt> NaN und &plusmn;Infinity
 * liefert diese Methode {@link Double#toString} zur�ck.
 */

Auch hier muss die Enumeration "enum FormatType {fix, exp};" selber
definiert werden. Man beachte bei den folgenden Beispielen die Verwendung
von ',' anstelle von '.' bei der Ausgabe. Wir bekommen also in der Tat
Gleitkommazahlen und nicht Gleitpunktzahlen geliefert, wie sich das auch
geh�rt, wenn die 'lokalen Einstellungen' auf Deutschland gesetzt sind.
Wer arabische oder indischen Ziffern bevorzugt, kann auch dies erreichen -
zur Verwendung von 'Locales' im Zusammenhang mit DecimalFormat verweisen
wir auf die Dokumentation. Die beiden Beispiele von oben nehmen, mit den
Voreinstellungen der deutschen Locale, folgende Gestalt an:

Beispiel: d = -Math.exp(702); for (int scale = 0; scale < 6; scale++)
System.out.println(scale+" -> "+format(d, scale, FormatType.exp));

0 -> -7E304
1 -> -7,5E304
2 -> -7,49E304
3 -> -7,494E304
4 -> -7,4942E304
5 -> -7,49422E304

Beispiel: d = Math.PI*10000.0; for (int scale = 0; scale < 6; scale++)
System.out.println(scale+" -> "+format(d, scale, FormatType.fix));

0 -> 31416
1 -> 31415,9
2 -> 31415,93
3 -> 31415,927
4 -> 31415,9265
5 -> 31415,92654

Bequeme Makros machen die Funktion jetzt gebrauchsfertig:
public static String formatFix2 (double d) {
    return format (d, 2, FormatType.fix);
}
public static String formatExp2 (double d) {
    return format (d, 2, FormatType.exp);
}

In vielen Anwendungen sind die Anforderungen an die Formatierung jedoch
wesentlich komplexer, weil dabei auch der f�r die Anzeige zur Verf�gung
stehende Platz ber�cksichtigt werden muss. Eine Basisklasse daf�r, die
sich auch f�r eigene Experimente eignet, kann man hier finden:
<URL:http://www.javajungle.de/OpenSource/DecimalFormat/>

::: 4. Runden  plus  Formatieren :::::::::::::::::::::::::::::::::::::::::

Als letztes eine Warnung: DecimalFormat verwendet /intern/ auch eine
Rundung, und zwar - fest verdrahtet - RoundingMode.HALF_EVEN. Das ist
schwerlich etwas anderes als ein Design-Bug, denn damit wird die
Verwendung der 7 anderen Rundungsarten von BigDecimal in Verbindung mit
dieser Formatierungsklasse problematisch.

Insbesondere sollte jeder, der DecimalFormat verwendet, sich klar dar�ber
sein, dass hier nicht kaufm�nnisch gerundet wird! Dazu noch ein Beispiel:

Das einfache dform2 = new java.text.DecimalFormat("0.00") beschert
folgende '�berraschung' beim Ausdruck einer Rechnung:

dform2( 10.495 ) -> 10,50
dform2( 10.505 ) -> 10,50
dform2( 10.515 ) -> 10,52

Zum Gl�ck bei�t sich die interne Rundung von DecimalFormat nicht mit einer
vorgeschalteten Aufrundung, sofern es nur um das Formatieren geht, so dass
sich dieses Problem so l�sen l��t:

public static String formatFixUp2 (double d) {
    return formatFix2(roundUpFix2(d));
}

formatFixUp2( 10.495 ) -> 10,50
formatFixUp2( 10.505 ) -> 10,51
formatFixUp2( 11.515 ) -> 11,52

Aber dieses Beispiel ist in erster Linie zur Illustration des Gesagten
gedacht. Denn bei kaufm�nnischen Rechnungen gilt es die Maxime von Paul
Ebermann zu befolgen: "Beim Rechnen mit Geld verwende man NIE 'double'."
Zu diesem Thema lese man auch den zweiten Link, der unten angegeben ist.

::: 5. Zusammenfassung  ::::::::::::::::::::::::::::::::::::::::::::::::::

  ----------------------------------------------------
       RUNDEN              |       FORMATIEREN
  ----------------------------------------------------
                     d = PI*10000.0;
   Nachkomma-Stellen       |  Fixpunkt-Format
   roundUpFix2(d)          |  formatFix2(d)
   Wert: double 31415.93   |  Wert: String "31415,93"
  ----------------------------------------------------
                     d = -exp(702);
   Tragende Stellen        |  Exponential-Format
   roundEvenExp2(d)        |  formatExp2(d)
   Wert: double -7.49E304  |  Wert: String "-7,49E304"
  ----------------------------------------------------

In dieser Gegen�berstellung wurde der Einfachheit willen ein Spezialfall
gew�hlt, f�r die allgemeine Darstellung gilt Analoges.

::: 6. Links und Literatur :::::::::::::::::::::::::::::::::::::::::::::::

*** Zur Verwendung der API:
<URL:http://java.sun.com/docs/books/tutorial/i18n/format/
decimalFormat.html>
<URL:http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents_p.html>
*** Grunds�tzliches zur (dezimalen) Gleitkomma-Arithmetik:
<URL:http://www2.hursley.ibm.com/decimal/decimal.html>
<URL:http://www2.hursley.ibm.com/decimal/decifaq.html>


3.13.3. Wie kann ich in Java Zufallszahlen im Bereich 0..n erzeugen?
        Autor: Markus Reitz, Uwe G�nther
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Zur Erzeugung von Zufallszahlen bietet Java das Random-Objekt. Bevor
Zufallszahlen erzeugt werden k�nnen, mu� ein solches Objekt erzeugt
werden, wobei ein  Random-Seed  genannter Zahlenwert �bergeben wird, der
Anteil an der Berechnung von Zufallszahlen hat. Generell mu� man sagen,
da� es sich bei auf dem Computer erzeugten Zufallszahlen um keine echten
zuf�lligen Zahlenfolgen handelt, der Begriff Pseudo-Zufallszahlen trifft
das Ganze besser. Grundlage dieser Zahlen sind Generator-Funktionen, die
eine mehr oder minder zuf�llig erscheinende Folge von Zahlen erzeugen.

F�r die Berechnung der Zahlen spielt der Random-Seed (quasi der Samen f�r
die Berechnung) eine gro�e Rolle. Wird dieser Random-Seed m�glichst
zuf�llig gew�hlt, so sind die resultieren-den Zahlenfolgen beinahe echte
Zufallszahlen. In der Praxis hat es sich als brauchbar erwiesen, als
Random-Seed die jeweils aktuelle Systemzeit zu benutzen, damit
gew�hrleistet ist, da� sich der Seed m�glichst h�ufig �ndert.

Damit erzeugt man ein Random-Objekt am Besten wie folgt:

    Random zufall = new Random(System.currentTimeMillis());

oder

    Random zufall = new Random();

Wobei der Default-Kostruktor intern auch nur

    this(System.currentTimeMillis());

aufruft, wie die Firma Sun in ihrer Online Dokumentation schreibt.

Mit Hilfe der Member-Funktion nextInt() wird die n�chste erzeugte
Integerzahl geliefert. In einem Gro�teil der F�lle m�chte man jedoch
nicht Integerzahlen haben, die auch negative Werte annehmen k�nnen,
sondern Zahlen im Bereich von 0 bis n. Hier kommt eine Variation der
nextInt() Methode ins Spiel, deren Anwendung die folgende Zeile
demonstriert:

    zahl = zufall.nextInt(n+1);

Ist einem die Saat von Random nicht zuf�llig genug, dann sollte man die
Klasse SecureRandom aus dem Package java.security verwenden. Hier werden
unter anderem je nach Plattform Betriebsystem spezifische Mechanismen
gew�hlt, wie zum Beispiel unter UNIX /dev/urandom.


3.14. [MISC] - Alles, was nicht in eine der anderen Rubriken pa�t.
------------------------------------------------------------------

3.14.1. Ich komme mit dem import-Statement nicht klar, was mache ich
        falsch?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:

In einem Programm kommen folgende beide import-Statements vor:

    import java.awt.*;
    import java.awt.event.*;

Warum reicht nicht das erste Statement aus, um die n�tigen Klassen und
Interfaces zu importieren?

Intuitiv w�rde man sagen, da� mit Hilfe des  *  alle Klassen und
Interfaces importiert werden, die unterhalb des Pfades java.awt stehen,
doch leider ist dies nicht so. Mit import java.awt.*; werden nur alle
Klassen importiert, die im Verzeichnis java.awt stehen, nicht jedoch
Klassen, die noch tiefer verschachtelt abgespeichert sind. Deshalb ist
das zweite import-Statement n�tig, welches alle Klassen in
java.awt.event importiert.


3.14.2. Warum gibt es Probleme bei final Werten in Verbindung mit
        elementaren Typen?
        Autor: Markus Reitz, Paul Ebermann
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Angenommen, eine Klasse A ist wie folgt definiert:

public class A {
    final static boolean test = true;
}

Aus irgendeinem Grund wird die Definition der Klasse A auf Folgendes
ge�ndert:

public class A {
    final static boolean test = false;
}

Die Klasse A wird neu compiliert und eine neue Klassendatei erzeugt.
Alle anderen Klassen, die das in Klasse A definierte Feld verwenden,
m��ten nun mit dem korrigierten Wert false arbeiten.
Probiert man dies in der Praxis aus, so stellt man fest, da� dies
nicht der Fall ist. Der Grund liegt in der Sprachdefinition der Sprache
Java. Ein primitiver (elementarer) Datentyp, der das Modifiziererpaar
final static tr�gt, wird vom Compiler als Konstante behandelt und kann
�berall, wo er im Programm auftritt, vom Compiler direkt durch den Wert
ersetzt werden. Um also zu erreichen, da� sich die in der Klasse A
gemachte �nderung auf alle sie benutzenden Klassen auswirkt, m�ssen
alle betroffenen Klassen neu �bersetzt werden. Dies gilt aber nur, wenn
der Wert tats�chlich mit einer Compile-Zeit-Konstante initialisiert wird.

Ein Ausweg aus diesem Dilemma stellt hier die Verwendung des
Typ sicheren enum (type safe enum) dar, siehe weiter unten.


Eine weitere Typ sichere Variante findet sich in folgendem Beispiel:

public class A {
    final static boolean test = new Boolean(true).booleanValue();
}

Ge�ndert dann:

public class A {
    final static boolean test = new Boolean(false).booleanValue();
}


3.14.3. Was bedeuten "$" im Namen von Class-Files?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das Dollarzeichen innerhalb eines Klassennamens taucht auf, wenn innere
Klassen, also Klassen, die innerhalb einer anderen Klasse definiert sind,
verwendet werden. Somit ist

    Testklasse$InnereKlasse.class

die Class-Datei der inneren Klasse "InnereKlasse", die innerhalb der
Klasse  Testklasse  definiert worden ist.


3.14.4. Wie lassen sich Bilder im Dateiformat XYZ laden oder speichern?
        Autor: Marco Schmidt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Seit Java 1.0 lassen sich mit java.awt.Toolkit GIF- und JPEG-Dateien
laden, seit Version 1.3 auch PNG (genaugenommen nicht nur aus Dateien,
sondern von beliebigen URLs und sogar aus Byte-Arrays). Das Speichern
von Bildern in diesen oder anderen Formaten wird nicht unterst�tzt. Da
weder java.awt.Image noch java.awt.image.BufferedImage die
Schnittstelle Serializable implementieren, lassen sich auch die
eingebauten Routinen zum Objekt-I/O nicht verwenden.

Eine Notl�sung stellt eventuell die Verwendung von PixelGrabber bzw.
MemoryImageSource aus java.awt.image dar. Mit ersterem lassen sich
Pixel als RGBA-int-Werte aus einem beliebigen java.awt.Image-Objekt
extrahieren, mit letzterem erzeugt man ein Image-Objekt aus solchen
"int-Pixeln". Lesen und Schreiben von int-Arrays unterst�tzen u. a.
DataIn/OutputStream bzw. ObjectIn/OutputStream. Dabei ist zu bedenken,
da� dieser Ansatz vier Bytes pro Pixel verbraucht. Eventuell f�hrt die
zus�tzliche Verwendung von
java.util.zip.DeflaterOut/InflaterInputStream zu Einsparungen.

F�r g�ngige Dateiformate sind zahlreiche externe L�sungen verf�gbar,
sowohl frei als auch kommerziell, in stark unterschiedlicher Qualit�t.
Unter
<URL:http://www.geocities.com/marcoschmidt.geo/java-image-coding.html>
befindet sich eine Liste. Die Bibliothek JIMI
<URL:http://java.sun.com/products/jimi/> ist ein guter Einstiegspunkt,
sie ist (seit Sun sie aufgekauft hat) kostenlos erh�ltlich und deckt eine
gr��ere Anzahl Formate ab. Das Package com.sun.image.codec.jpeg - zum
Laden und Speichern von Bildern im JPEG-Format - ist in neueren
Sun-JREs und JDKs enthalten, man kann sich jedoch nicht darauf
verlassen, es auch in anderen Java-Distributionen zu finden.

Bei Verwendung des LZW-Algorithmus' (z. B. in GIF bzw. TIFF/LZW) ist
darauf zu achten, da� sowohl kommerzielle als auch Freeware-Produkte
in bestimmten L�ndern (inkl. USA und Deutschland) eine Lizenz beim
Patentbesitzer Unisys erwerben m�ssen (siehe auch
<URL:http://dmoz.org/Computers/Data_Formats/Graphics/2D/GIF/>. Als
Alternative zu GIF ist PNG gut geeignet, da es GIFs Einsatzgebiet -
mit Ausnahme von Animationen - abdeckt und in modernen Browsern
unterst�tzt wird.

Mit Java 1.4 wurde ein eigenst�ndiges Package zum Laden und Speichern
eingef�hrt: javax.imageio. Dieses unterst�tzt zun�chst nur das Lesen
von GIF, JPEG und PNG sowie das Schreiben von JPEG und PNG. Allerdings
plant Suns JAI-Team (Java Advanced Imaging, eine Java-Bibliothek f�r
Bildverarbeitung), fast alle Codecs aus JAI zu portieren, so da� sie
der Spezifikation von javax.imageio folgen. Das schlie�t BMP, PNM
(Portable Anymap) und TIFF ein. In Zukunft soll JAI f�r Codecs
komplett auf die ImageIO-API aufbauen. Eine Einf�hrung befindet sich
auf <URL:http://java.sun.com/j2se/1.4/docs/guide/imageio/> oder bei
installiertem JDK unterhalb des Installationsverzeichnisses in
/docs/guide/imageio/index.html.

Auf <URL:http://www.jalice.net/myJava.htm> finden sich zahlreiche
Code-Beispiele und weiterf�hrende Informationen zum Umgang mit
Bildern, Java2D und der neuen ImageIO-API.


3.14.5. Was geht nicht mit Java?
        Autor: Martin Erren
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Einige Features sind sehr systemnah und k�nnen wegen der
Plattformunabh�ngigkeit von Java nicht direkt gel�st werden.

Oft ist liegt dabei das eigentliche Problem eher im Ansatz,
weil zu plattformspezifisch gedacht wird, statt g�ngige
Java-Paradigmen umzusetzen. So sind z.B. Properties jederzeit
Environment Variablen vorzuziehen.

Ansonsten schafft ein entsprechendes System.exec(...) Abhilfe
oder ein Bibliotheksaufruf, z.B. �ber JNI (Java Native Interface).
Ein f�r jede Plattform einzeln zu l�sendes Problem.

Einige Bibliotheken wie JavaComm sind bereits f�r die
verschiedensten Plattformen implementiert.

CPU:
 Daten wie Taktfrequenz auslesen.

Speicher:
 Gesamtgr�sse ermitteln, direkt manipulieren.

Laufwerke:
 Genauen Laufwerkstyp erkennen (CDRom,...)
 CD auswerfen

Filesystem:
 Partitionsgr�sse bestimmen.
 Linux: genauen file type feststellen (block/stream devices,...)
   einzelne Berechtigungen auslesen
 Windows: Verkn�pfungen folgen
   Native L�sung:
    <URL:http://www.tolstoy.com/samizdat/jconfig.html>

Textconsole:
 Bildschirm l�schen
 cursor position setzen
 Farben
   Native L�sung:
    <URL:http://www.bmsi.com/tuipeer/>
   Pure java (�ber ANSI):
    <URL:http://purl.org/NET/ePaul/#pps>

Desktop:
 Nicht reckeckige Fenster
   Native L�sung:
    <URL:http://www.l2fprod.com/software/skinlf/>
 Tray Icon
   Native L�sung beschrieben bei:
    <URL:http://www.nevaobject.com/_docs/_coroutine/coroutine.htm#example>
 Fenster immer im Vordergrund halten
   Native L�sung:
    <URL:http://www.mysrc.net/lib/java/MySRC-AlwaysOnTop-090.zip>

Netzwerk, Schnittstellen:
 ICMP
 Serielle + Parralle Schnittstelle ansteuern
   Native L�sung:
    <URL:http://java.sun.com/products/javacomm/>

Tastatur:
 SHIFT, CNTRL, ALT alleine gedr�ckt
 Windows Taste
 Standardeingabe ungepuffert lesen (statt flush bei \n)

Maus:
 Scrollrad (m�glich ab JDK 1.4)
   Native L�sung <URL:http://www.codeproject.com/java/mousewheel.asp>

Betriebssystem:
 Environment-Variablen lesen(unm�glich seit 1.2)/schreiben.
 System-Shutdown.
 Windows: Registry lesen/schreiben (eingeschr. m�glich ab JDK 1.4)
  Native L�sung: <URL:http://www.trustice.com/java/jnireg/>


3.14.6. Wie kann ich in meinem Java-Programm ein HTML-Dokument
        anzeigen lassen?
        Author: Marco Schmidt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Es gibt zwei L�sungsans�tze, das Einbinden von Java-Code, der dies
leistet, oder das Aufrufen eines externen Programms (Browser).

* Man kann das Dokument selbst in einer GUI-Komponente anzeigen
  lassen. Das hat den Vorteil, da� man unabh�ngig von externen
  Programmen ist.

  In der Standardbibliothek gibt es seit Java 1.2 in der Hierarchie
  javax.swing.text.html entsprechenden Code. Der ist allerdings nur
  f�r Swing-Oberfl�chen geeignet, nicht f�r AWT. Dar�ber hinaus wird
  nur HTML 3.2 unterst�tzt.

* Eine Mischl�sung ist die Verwendung eines reinen Java-Browsers wie
  HotJava <URL:http://java.sun.com/products/hotjava/3.0/>. Dieser
  Browser k�nnte - nach Kl�rung der rechtlichen Details - mit dem
  Programm ausgeliefert werden und m��te �berall dort funktionieren,
  wo auch die eigene Java-Applikation ausgef�hrt wird. HotJava
  unterst�tzt auch nur HTML 3.2, ben�tigt aber nur das AWT und Java 1.1.

* Eine �hnliche L�sung ist der ebenfalls in reinem Java geschriebene
  kommerzielle ICEbrowser:
  <URL:http://www.icesoft.no/ps_browser_overview.html>.

* BrowserLauncher ist eine Java-Klasse (Freeware) zum Starten des
  Standard-Browsers: <URL:http://browserlauncher.sourceforge.net/>

* Ein JavaWorld-Artikel versucht ebenfalls, den Standardbrowser zu
  finden und zu starten: "Java Tip 66: Control browsers from your Java
  application"
  <URL:http://www.javaworld.com/javaworld/javatips/jw-javatip66.html>

* Die kommerzielle Bibliothek JConfig bietet �hnliches, unter
   Verwendung von nativem Code:
  <URL:http://www.tolstoy.com/samizdat/jcdocs/overview.html#WBLaunch>


3.14.7. Unter Windows werden in der Konsole (DOS-Eingabeaufforderung)
         die Umlaute falsch ausgegeben. Wie kann ich das korrigieren?
         Author: Peter Karp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Das Problem liegt in der verwendeten Codepage. Standardm��ig geht ein
Java-Programm von der Codepage Latin1 aus, w�hrend in der Windows-Konsole
eine andere Codepage (hier meist CP850) verwendet wird.

Intern werden bei Java Zeichens�tze in Unicode codiert. Zur Ausgabe muss
das Java-Programm die Unicode-Kodierung in die passende Kodierung der
aktuellen Codepage konvertieren, welche f�r ein Zeichen -- im Unterschied
zu Unicode -- nur ein Byte verwendet. Die Umlaute liegen bei verschiedenen
Kodierungen oft nicht an der gleichen Stelle.

Die aktive Codepage kann unter Windows 2000/XP mit dem Befehl

    chcp

bzw. unter Windowx 9x mit dem Befehl

    mode con:cp

angezeigt werden.

Standardm��ig ist bei einem deutschen Windows Codepage 850 (manchmal auch
437) in der Konsole aktiv. In den "normalen" Windows-Programmen wird immer
der MS-ANSI-Zeichensatz (Codepage 1252) verwendet. MS-ANSI ist weitgehend
mit Latin1, welches z.B. unter Linux verwendet wird, identisch. Die
7-Bit-ASCII-Zeichen und die deutschen Umlaute sind an den gleichen
Stellen.


Somit gibt es zwei grundlegend verschiedene L�sungen:

1) Man �ndert die verwendete Codepage in Windows auf Codepage 1252 oder
Latin1.

a) Die Unix-Umgebung "Cygwin" f�r Windows benutzt Latin1 als Codepage.
Cygwin findet man unter www.cygwin.com und stellt unter anderem die
�blichen Unix-Tools und eine Shell zur Verf�gung.

b) Unter Windows 2000/XP kann mit dem Befehl chcp die aktive Codepage
gewechselt werden. Dies alleine stellt aber noch nicht die korrekte
Ausgabe der Umlaute sicher, da auch der verwendete Font die richtige
Kodierung verwenden muss.

Sinnvollerweise erstellt man sich eine Verkn�pfung zu einem neuen
Konsolenfenster, dass Codepage 1252 und einen dazu passenden Font
verwendet, da man in den anderen Konsolenfenstern in der Regel
wahrscheinlich weiterhin Codepage 850/437 verwenden will, um zu den
DOS-Programmen kompatibel zu bleiben:

1. neue Verk�pfung auf Desktop erstellen
2. Speicherort angeben: %SystemRoot%\system32\cmd.exe /k chcp 1252
3. Name angeben: Konsole1252
4. fertigstellen
5. Eigenschaften der Verkn�pfung �ndern und als Schriftart
   "Lucida Console" definieren. Optional gibt man noch den Pfad zu dem
   Verzeichnis mit den Java-Programmen bei "Ausf�hren in:" an.
6. fertig, das wars - wird der Shortcut nun f�r Java-Programme verwendet,
   gibts keine Probleme mehr mit Umlauten

Der Font "Lucida Console" ist ein TrueType-Font im OpenType-Format, der
die Unicode-Codierung unterst�tzt und daher die Zeichen f�r alle
verf�gbaren Codepages beinhaltet. Die sog. "Rasterschriftart" hingegen
liegt immer in der OEM-Kodierung vor. Dabei ist die OEM-Kodierung, die
Kodierung, die im jeweiligen Land f�r "DOS-Programme" �blich ist. F�r
Deutschland ist das Codepage 850, f�r Amerika Codepage 437 usw. Falls man
das Aussehen der "Lucida Console" nicht mag, kann man einen neuen Font
installieren, der das OEM-Flag gesetzt hat, aber trotz dieses Flags die
Kodierung f�r Codepage 1252 verwendet. Diesen Font New1252.FON, und eine
Erkl�rung wie dieser zu nutzen ist, findet sich auf der Homepage von
<URL:http://www.uwe-sieber.de>.


2) Alternativ kann im Java-Programm selbst sichergestellt werden, dass die
aktive Codepage zur Ausgabe ber�cksichtigt wird.

Erstelle eine neue Klasse f�r dein Tool-Paket und
rufe sie mit

        new KonsolenUmlaut();

auf, oder packe das folgende Code-Beispiel in die Klasse, die das
Problem betrifft.

Diese M�glichkeit sollte aber nicht fest codiert werden, sondern optional
�ber ein Argument beim Start des Programmes mitgegeben werden k�nnen. Eine
weitere M�glichkeit w�re die Ausgabe des Befehls 'mode con:cp' auszuwerten
und dann die Codepage entsprechend zu �bergeben.

Code-Beispiel
=============

/**
 * Gibt die Umlaute unter Windows in Codepage 850 aus. Eingabe von
 * der Konsole oder Dateioperationen sind davon unber�hrt und haben
 * auch die Umlaute korrekt nach Latin1.
 */
package myToolsPackage;

import java.io.*;

public final class KonsolenUmlaut {
    public KonsolenUmlaut() {
        String sys = System.getProperty("os.name");
        if (sys.startsWith("Windows")) {
            try {
                System.setOut( new PrintStream( new
                            FileOutputStream(FileDescriptor.out),
                            false, "cp850"));
                System.setErr( new PrintStream( new
                            FileOutputStream(FileDescriptor.err),
                            true, "cp850"));
            } catch (IOException e) { e.printStackTrace(); }
        }
    }
}


3.15. [ERROR] - Fehlermeldungen
-------------------------------

3.15.1. Warum findet Java den Konstruktor nicht?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:

public class Test {

    private int a;
    private int b;

    public void Test (int a , int b) {
        this.a = a;
        this.b = b;
    }

    public static void main (String[] args) {

        //Und hier eine Fehlermeldung.
        Test myTest = new Test (12, 13);
    }
}

Versucht man die obige Klasse zu �bersetzen, so meckert der Compiler
mit der Meldung  Wrong number of arguments in constructor ... .
Die L�sung des Problems ist einfach: Konstruktoren besitzen keinen
R�ckgabetyp, auch nicht void. In obigem Beispiel hat man n�mlich nicht
den Konstruktor f�r die Klasse Test definiert, sondern eine Funktion,
die den selben Namen wie die Klasse hat. Weiter unten versucht man nun,
den vermeintlich definierten Konstruktor aufzurufen und bekommt die
beschriebene Fehlermeldung.

L�sung:

public class Test {

    private int a;
    private int b;

    public Test (int a , int b) {
        this.a = a;
        this.b = b;
    }

    public static void main (String[] args) {

        //Hier kommt jetzt keine Fehlermeldung mehr!
        Test myTest = new Test (12 , 13);
    }
}


3.15.2. Warum bekomme ich eine "NoClassDefFoundError" Fehlermeldung
        beim Starten von java?
        Autor: Markus Reitz, Sascha Raabe
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Der Grund ist einfach: Man mu� der Java-Laufzeitumgebung mitteilen, wo
sich die *.class-Dateien des Programms befinden, damit die Ausf�hrung
erfolgen kann. Dies erreicht man bei der SUN-Implementierung mit dem
Aufrufparameter -cp f�r Classpath oder man setzt die Umgebungsvariable
CLASSPATH auf das Verzeichnis, in dem sich die *.class-Dateien befinden.

Ausserdem muss beim Aufruf des Programms der vollst�ndige Klassenname
angegeben werden. Dieser besteht aus Packagenamen und Name der Java
Klasse.

Beispiel:
Die Java Klasse "MyApp" befindet sich im Package "de.foo.bar". Der
Aufruf der Klasse erfolgt somit �ber:

java de.foo.bar.MyApp

Dabei ist auf Gross- und Kleinschreibung zu achten.

3.15.3. Warum bekomme ich eine "Couldn't read <Name>" Fehlermeldung  beim
        Kompilieren mit javac?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In Java gilt die einfache Regel, da� der Name der Datei, in der die
Klasse gespeichert ist, identisch mit dem Klassennamen sein mu�, wobei
auf die korrekte Gro�- und Kleinschreibung zu achten ist.


3.15.4. Warum bekomme ich eine "class <Name> must be defined in a file
        called <Name>" Fehlermeldung  beim Kompilieren von javac?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hier gilt analog das unter dem vorherigen Punkt angef�hrte. Eine Datei,
in der der Quelltext der Klasse gespeichert ist, mu� den selben Namen
besitzen wie die Klasse im Quelltext.


3.15.5. Warum wird beim Zugriff auf ein korrekt initialisiertes Objekt-
        Array eine NullPointerException geworfen?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:

public class A {
    public String text;
}

public class Test {
    public static void main (String[] args) {
        A array = new A[10];
        for(int i = 0; i < 10; i++) {
            //wirft NullPointerException
            array[i].text = "Test";
        }
    }
}

F�hrt man das Programm aus, so erh�lt man die im Programmtext erw�hnte
NullPointerException, obwohl doch alles eigentlich ganz in Ordnung
aussieht. Der Teufel steckt aber im Detail. Mit A array[] = new A[10]
wird eben nicht ein Array von zehn Objekten vom Typ A erzeugt, sondern
nur ein Array, welches zehn Referenzen auf Objekte vom Typ A enth�lt,
die eigentlichen Objekte werden damit nicht erzeugt.


L�sung:

public class A {
    public String text;
}

public class Test {
    public static void main (String[] args) {
        A array = new A[10];
        for(int i = 0; i < 10; i++) {
            array[i] = new A();
            //wirft keine NullPointerException mehr
            array[i].text = "Test";
        }
    }
}


3.15.6. Warum bekomme ich eine NullPointerException, wenn ich
        versuche, auf Methoden oder Attribute von in einem Array
        gespeicherten Objekten zuzugreifen?
        Autor: Michael Paap
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vermutlich hast Du zwar den Array erzeugt, nicht jedoch die
Objekte. Dann sind die Fields Deines Array mit null
initialisiert, d.h. die Referenzen existieren zwar, nicht
jedoch die referenzierten Objekte.

Abhilfe:

Um z.B. einen Array von sechs Buttons zu erzeugen, geht man
so vor:

Button[] myButtons = new Button[6];

for (int i = 0; i < myButtons.length; i++) {
    myButtons[i] = new Button();
}


3.15.7. Warum meckert der Compiler bei nicht initialisierten final
        Variablen
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ab Java 1.1 ist folgender Code g�ltig:

public class Test {
    final int i;

    public Test(int i) {
        //finale Variable this.i wird mit dem Wert
        //von i initialisiert.
        this.i = i;
    }

    public Test() {
        //Fehler die finale Variable this.i muss auch in diesem
        //Konstruktor initialisiert werden.
    }
}

Es ist also m�glich, Variablen mit finalen Werten zu erzeugen, deren
finaler Wert beim ersten initialisieren der Variablen einmalig
festgelegt werden kann. Allerdings kann dies nur innerhalb eines
Konstruktors geschehen und es mu� auf jeden Fall eine Initialisierung
der Variablen erfolgen, denn ansonsten meldet der Compiler Fehler.


3.15.8. Was hat die Compilerfehlermeldung "... is deprecated" zu
        bedeuten?
        Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Diese Meldung erh�lt man normalerweise dann, wenn �ltere Java-Programme
mit einer neuen Version des Compilers �bersetzt werden sollen. Die
Meldung ist nur eine Warnung, also kein richtiger Fehler, die
Funktionalit�t des Programms wird nicht beeintr�chtigt. Die Methode,
die bei der Meldung "... is deprecated" genannt wird, sollte aber nach
M�glichkeit nicht mehr im Programm verwendet werden, da das Konzept der
Klasse ver�ndert wurde und deshalb die Methode unter Umst�nden in
neueren Versionen nicht mehr implementiert sein wird. Treten also solche
Meldungen beim Compilieren auf, so sollte man die entsprechenden
Methoden durch die empfohlenen Varianten ersetzen, damit gew�hrleistet
ist, da� das Programm auch mit sp�teren Versionen von Java einwandfrei
�bersetzt werden kann.


3.16. [ClassLoader] - Alles �ber Classloader
--------------------------------------------

3.16.1 Wie funktionieren Classloader?
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
F�r das Laden von Klassendefinitionen sind in Java Exemplare der
Klasse java.lang.ClassLoader zust�ndig.[1] Jede Klasse ist assoziiert
mit dem Classloader (kurz: CL), �ber den sie geladen wurde und kann
�ber diesen im Zusammenhang mit ihrem voll qualifizierten Klassennamen
eindeutig identifiziert werden.

Klassen mit gleichem Namen aber unterschiedlichen CL gelten als
verschieden; Casts zwischen den beiden Klassen funktionieren nicht. Da
die Klasse ueblicherweise auch bei der equals()-Operation herangezogen
wird, werden auch Objekte mit gleicher Struktur und gleichen Membern,
deren Klassen gleiche Namen aber unterschiedliche CL haben, als
unterschiedlich betrachtet.

Die im System vorhandenen CL bilden eine baumartige Hierarchie, in der
Anfragen nach oben weitergereicht werden k�nnen (und sollen), und die in
einem 'obersten' CL (dem sog. Bootstrap-CL) wurzelt. Der Ladevorgang
teilt sich �blicherweise auf in folgende Schritte:

1. Es wird eine Anfrage an den CL gestellt, entweder explizit �ber
ClassLoader#loadClass(), indirekt �ber Class#forName() oder implizit
durch Verwendung eines Klassennamens im Sourcecode. In den letzten
beiden F�llen wird der CL der Klasse, auf der forName() aufgerufen
wird bzw. derjenigen, aus welcher der gerade ausgef�hrte Code stammt,
verwendet.

2. Der CL �berpr�ft, ob die Klasse bereits von ihm geladen wurde.
Falls ja, sollte er das entsprechende Klassenexemplar gecached
haben[2] - dieses wird zur�ckgeliefert, fertig.

3. Der CL delegiert die Anfrage zun�chst an den ihm �bergeordneten CL,
der wiederum bei Punkt 2 mit der Bearbeitung beginnt. Kann dieser ein
Klassenexemplar liefern, wird dieses zur�ckgegeben - fertig.

4. Der CL holt den Bytecode - je nach CL kann dieser aus
unterschiedlichen Quellen stammen: .class-datei, .jar-datei, URL,
programmatisch generiertes Byte-Array, usw.

5. Der Bytecode wird per ClassLoader#defineClass() in ein Exemplar von
java.lang.Class umgewandelt.

6. Gegebenenfalls werden referenzierte Klassen und Interfaces rekursiv
geladen ('resolving').

(Wohlgemerkt: 'Der' CL einer Klasse ist derjenige in der
Delegationskette, der sie tats�chlich geladen hat (Schritt 2 oder 5),
nicht unbedingt derjenige, auf dem urspr�nglich loadClass() aufgerufen
wurde.)

Diese Vorgehensreihenfolge ist zwar erw�nscht, kann aber teilweise
nicht erzwungen werden. Insbesondere der Vorrang der Delegation kann
in seltenen F�llen ignoriert werden, so z.B. beim Webapp-CL von
Tomcat[9].

Bei Vergleichen von Klassen oder Objekten, beim Laden von Ressourcen
(s.u.), bei Singletons[7] und bei 'Typesafe Enumerations'[8] kann man
unter unerwarteten CL-Bedingungen schweren Schiffbruch erleiden.

N�heres zum CL-Mechanismus findet man z.B. bei [4], [5] und [6].


3.16.2 Warum macht der Classloader im Servlet-Container Probleme?
       Warum funktioniert das Einlesen von Ressourcen ueber den
       Classloader bei mir nicht?
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
�blicherweise muss man sich nicht besonders oft mit CL befassen.
Ausnahmen sind Probleme beim Laden von Ressourcen aus dem Classpath
(=> dclj-FAQ 3.3.6.) und das Schreiben von Bibliotheken oder Klassen,
die im Kontext CL-technisch komplizierterer Umgebungen wie J2EE- oder
Servlet-Containern zur Anwendung kommen k�nnen oder sollen.

Es gibt mehrere M�glichkeiten, direkt oder indirekt an unterschiedliche
CL zu geraten: �ber die Klasse, die den gerade ausgef�hrten Code enth�lt,
�ber eine beliebige andere Klasse oder �ber
Thread.currentThread().getContextClassLoader(). �blicherweise will man
sich m�glichst tief in der CL-Hierarchie einklinken.

In Servlet-Containern f�hrt man meist recht gut mit dem Context-CL des
aktuellen Threads, da der Container sich drum kuemmert, dass dieser
passend gesetzt ist, ebenso im Beispielcode. Anderswo ist das eine recht
wacklige Angelegenheit, da dieser Context-CL praktisch beliebig gesetzt
und wieder neu gesetzt werden oder auch null sein kann.

Das Laden �ber eine bestimmte Klasse bringt hingegen Probleme, wenn
deren CL kein Blatt der CL-Hierarchie darstellt und es m�glich ist,
dass dynamisch auf tieferliegende Elemente zur�ckgegriffen werden soll.
Beispiel: Eine Klasse in einem shared- oder common-Verzeichnis eines
Servlet-Containers will zur Laufzeit eine Webapp-spezifische Klasse
laden.

Ein weiteres Problem mit dem Einlesen von Ressourcen ueber den CL ist,
dass man ggfs. die entsprechenden Security-Privilegien benoetigt. Diese
Einschraenkung ist bei Verwendung von Class#GetResource[AsStream]() nicht
gegeben.

Aufgrund der vielen sich ergebenden Fallstricke ist ein Einlesen von
Ressourcen ueber Class/Classloader in komplexeren Umgebungen nur sehr
bedingt zu empfehlen. Bei Problemen damit oder mit dem Laden von Klassen
ist es hilfreich, erst einmal die Struktur der CL-Hierarchie zu klaeren.


3.16.3 Wie lade ich eine Klasse neu?
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Im Wortsinn: Eigentlich gar nicht.

Von 'guten' CLs wird gefordert, dass sie auf Anfragen nach demselben
Klassennamen auch stets dasselbe Class-Exemplar liefern.[2] Wenn ein
CL sich nicht daran h�lt, k�nnte es im System zwei Klassen geben, die
per Definition identisch sind, aber eine ganz andere Struktur oder
zumindest unterschiedliche Methodendefinitionen haben - ein sicheres
Rezept f�r �rger.

Daher gilt seit Java 1.2: Eine Klasse kann nur entladen werden, wenn
der zugeh�rige CL nicht mehr reachable und damit reif f�r den GC
ist.[3] Demgem�ss k�nnen Klassen, die durch den Bootstraploader
geladen wurden, �berhaupt nicht entladen werden. Vorsicht ist im
Umgang mit �lteren VMs geboten: In Java 1.0 gab es �berhaupt kein
Class-Unloading; in Java 1.1 konnten Klassen geradezu beliebig
entladen werden, mit entsprechend verwirrenden Konsequenzen, z.B. bei
Verwendung des Singleton-Patterns.[7]

Wie erzeugt man nun trotz alldem den Effekt des 'Neuladens' von
Klassen? Man l�dt die ge�nderte Klassendefinition �ber einen neuen CL.
Damit sind Exemplare der alten Klasse inkompatibel zu Exemplaren der
neuen Version. �blicherweise 'vergisst' man beim Neuladen den alten
CL, so dass Exemplare der alten Klasse (so sie nicht anderweitig
referenziert werden) f�llig f�r den GC werden.

Um dieses Auswechseln der Klasse f�r den Rest der Anwendung
transparent zu halten, empfiehlt es sich, diese Klasse hinter einem
Interface zu verstecken. Das Interface ist dem �bergeordneten CL
bekannt und Anfragen danach werden vom Reloading-CL an diesen
delegiert, so dass �berall in der Anwendung dasselbe Interface bekannt
ist. Die '�nderbare' Klasse muss dieses Interface implementieren. Ihre
Definition wird dann �ber einen Reloading-CL geladen und ein Exemplar
erzeugt, das dem Rest der Applikation ausschliesslich als Auspr�gung
des Interface zur Verf�gung gestellt wird. Ein Beispiel dieses
Vorgehens findet sich in [4] und im Beispielcode.


3.16.4 Wie baue ich einen Plugin-Mechanismus?
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unter einem Plugin-Mechanismus versteht man gemeinhin eine
M�glichkeit, zur Compilezeit der Applikation noch unbekannte Klassen,
die �blicherweise dasselbe Interface implementieren, zum
Applikationsstart (oder irgendwann sonst zur Laufzeit) zu laden. Die
Plugin-Klassen (oder entsprechende Jars/Unterverzeichnisse) liegen
hierbei oft in einem besonderen Plugin-Verzeichnis, oder die
Klassennamen und Positionen im Dateisystem werden der Applikation �ber
eine Konfigurationsdatei mitgeteilt.

Zum Applikationsstart werden die Klassen �ber einen eigenen CL (das
kann ein selbstgeschriebener CL oder schlicht ein URLClassLoader[10]
sein) geladen und dem Rest der Applikation als Exemplar des
�bergeordneten Interfacetyps bekanntgemacht.

Beispiele f�r Plugin-Mechanismen findet man in IDEs, Servlet-Containern
und Webbrowsern. Beim Entwickeln eines Plugin-Frameworks oder eines
Plugins koennen einem schnell fiese CL-Probleme begegnen - [12] und [13]
aus dem Eclipse-Wiki liefern etwas Anschauungsmaterial.


3.16.5 Gibt's dazu auch Beispielcode?
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// $HOME/player/PluginPlayer.java
import java.io.*;
import java.net.*;

public class PluginPlayer {
  public static void main(String[] argv) {
    try {
      BufferedReader in =
          new BufferedReader(new InputStreamReader(System.in));
      // Plugin-Verzeichnis setzen
      final File plugindir = new File(argv[0]).getCanonicalFile();
      do {
        // Suche alle .class-Files im Plugin-Verzeichnis
        File[] pluginfiles = plugindir.listFiles(
            new FilenameFilter() {
              public boolean accept(File dir, String name) {
                return plugindir.equals(dir)
                    && name.endsWith(".class")
                    && name.indexOf("Plugin") > -1;
              }
            }
        );
        // Erzeuge einen Loader fuer dieses Verzeichnis
        URLClassLoader loader =
            new URLClassLoader(new URL[]{plugindir.toURL()});
        // Iteriere ueber alle .class-Files...
        System.out.println("Running plugins from: " + plugindir.toURL());
        int numplugins = pluginfiles.length;
        for (int plugincnt = 0; plugincnt < numplugins; plugincnt++) {
          // ...extrahiere den Klassennamen...
          String filename = pluginfiles[plugincnt].getName();
          String pluginname =
              filename.substring(0, filename.lastIndexOf("."));
          System.out.println("Running plugin: " + pluginname);
          // ...lade die Klasse, erzeuge eine Instanz und caste...
          Plugin plugin =
              (Plugin) (loader.loadClass(pluginname).newInstance());
          // ...setze den Context-Loader des ausfuehrenden Threads...
          Thread.currentThread().setContextClassLoader(loader);
          // ...rufe die entsprechende Methode auf...
          plugin.doIt();
          // ...und setze den Context-Loader zurueck.
          ClassLoader parentloader = loader.getParent();
          Thread.currentThread().setContextClassLoader(parentloader);
        }
        System.out.println("'q'[RET] to quit, [RET] to continue");
      }
      while (!"q".equals(in.readLine()));
    }
    catch (Exception exc) {
      exc.printStackTrace();
    }
  }
}

// $HOME/player/Plugin.java
public interface Plugin {
  void doIt() throws Exception;
}

// $HOME/plugins/CLTestPlugin.java
public class CLTestPlugin implements Plugin {
  // Laedt Klassen auf unterschiedliche Arten
  public void doIt() throws ClassNotFoundException {
    ClassLoader contextcl =
        Thread.currentThread().getContextClassLoader();
    Class ac1 =
        contextcl.loadClass("AnotherClass");
    Class ac2 = Class.forName("AnotherClass");
    String firstresult = (ac1 == ac2 ? "fine" :"inconsistent");
    System.out.println("Check #1: " + firstresult);

    ac1 = contextcl.loadClass("Plugin");
    ac2 = AnotherClass.class.forName("Plugin");
    Class ac3 = Plugin.class;
    String secondresult =
        (ac1 == ac2 && ac1 == ac3 ? "fine" :"inconsistent");
    System.out.println("Check #2: " + secondresult);
  }
}

// $HOME/plugins/AnotherClass.java
public class AnotherClass {
}

// $HOME/plugins/CLResourcePlugin.java
import java.io.*;

public class CLResourcePlugin implements Plugin {
  // Laedt einen Text als Ressource und gibt ihn aus
  public void doIt() throws IOException {
    InputStream instream = getClass().getResourceAsStream("msg.txt");
    BufferedReader inreader =
        new BufferedReader(new InputStreamReader(instream));
    String curline = null;
    while ((curline = inreader.readLine()) != null) {
      System.out.println(curline);
    }
    inreader.close();
  }
}

// $HOME/plugins/msg.txt
Hello, world!

// $HOME/plugins/CLListPlugin.java
public class CLListPlugin implements Plugin {
  // Listet alle beteiligten CL
  public void doIt() {
    ClassLoader contextcl= Thread.currentThread().getContextClassLoader();
    System.out.println("Context CL: " + contextcl);
    ClassLoader curcl = getClass().getClassLoader();
    while (curcl != null) {
      System.out.println(curcl);
      curcl = curcl.getParent();
    }
  }
}


3.16.6 ClassLoader Ressourcen zu 3.16.1 bis 3.16.5
       Autor: Ortwin Gl�ck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[1] java.lang.ClassLoader API-Doc
<URL:http://java.sun.com/j2se/1.4.1/docs/api/java/lang/ClassLoader.html>

[2] JLS 12.2
<URL:http://java.sun.com/docs/books/jls/second_edition/html/
execution.doc.html#44459>

[3] JLS 12.7
<URL:http://java.sun.com/docs/books/jls/second_edition/html/
execution.doc.html#74294>

[4] JavaWorld-Artikel Classloader Java 1.0 Style
<URL:http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html>

[5] JavaWorld-Artikel Classloader Java 1.1 Style
<URL:http://www.javaworld.com/javaworld/jw-03-2000/jw-03-classload.html>

[6] Sun-Tutorial Classloader Java 1.1 Style
<URL:http://developer.java.sun.com/developer/onlineTraining/Security/
Fundamentals/magercises/ClassLoader/index.html>

[7] JavaWorld-Artikel Classloader und Singletons
<URL:http://www.javaworld.com/javatips/jw-javatip52_p.html>

[8] JavaWorld-Artikel Typesafe Enumerations
<URL:http://www.javaworld.com/javatips/jw-javatip122_p.html>

[9] Tomcat Classloader-Howto
<URL:http://jakarta.apache.org/tomcat/tomcat-4.1-doc/
class-loader-howto.html>

[10] java.net.URLClassLoader API-Doc
<URL:http://java.sun.com/j2se/1.4.1/docs/api/java/net/URLClassLoader.html>

[11] SPI-Kapitel im Jar-Doc
<URL:http://java.sun.com/j2se/1.4.1/docs/guide/jar/
jar.html#Service%20Provider>

[12] Eclipse-Wiki Plugin-Development
<URL:http://eclipsewiki.swiki.net/114>

[13] Eclipse-Wiki Classloader Tricks
<URL:http://eclipsewiki.swiki.net/123>



4. B�cher zum Thema Java
========================

4.1. Kann mir jemand gute Literatur zum Thema Java empfehlen?
-------------------------------------------------------------
<URL:http://www.dclj.de/links.html> bietet eine kleine �bersicht �ber
B�cher, die zum freien Download zur Verf�gung stehen. Weiterhin bietet
die Seite <URL:http://www.accu.org/bookreviews> viele aufschlussreiche
Besprechungen von Java-B�chern.

Hier nochmal in aller K�rze:

* The Java Tutorial - <URL:http://java.sun.com/docs/books/tutorial/>
* Java ist auch eine Insel - <URL:http://www.java-tutor.com/>
* Go To Java 2 - <URL:http://www.javabuch.de/>
* Thinking in Java - <URL:http://www.mindview.net/Books/TIJ/>



In Buchform sind die folgenden Werke interessant:

* Go To Java 2 - Handbuch der Java-Programmierung

   Guido Kr�ger
   Addison-Wesley
   ISBN: 382731710X
   15. September 2000
   1224 Seiten
   <URL:http://www.javabuch.de/>

   - Eines der Standardwerke f�r angehende Javaprogrammierer und
     Kaffetrinker. Zumindest als Onlineversion sollte es sich jeder mal
     angeschaut haben, denn es bietet einen umfassenden und dennoch nicht
     zu sehr ins Detail gehenden �berblick ueber die verschiedenen
     Komponenten der Sprache Java.

* Java ist auch eine Insel - Programmieren f�r die Java 2-Plattform in
  der Version 1.4

   Christian Ullenboom
   Galileo Press
   ISBN: 3898421740
   Dezember 2001
   1239 Seiten
   <URL:http://www.java-tutor.com/javabuch/download.htm>

* Java. Programmierhandbuch und Referenz f�r die Java-2-Plattform
   - Einf�hrung und Kernpakete. Mit CD-ROM.

   Stefan Middendorf, Reiner Singer
   dpunkt-Verlag, Heidelberg
   ISBN 3920993829
   1999
   1256 Seiten


* Java2 Designmuster und Zertifizierungswissen

   Friedrich Esser
   Galileo Press
   ISBN 3934358667
   2001
   654 Seiten


* Einf�hrung in die objektorientierte Programmierung mit Java

   Ernst-Erich Doberkat,
   Stefan Di�mann Oldenbourg
   ISBN 3486247867
   2000
   315 Seiten


* Java Gently

   Judy M. Bishop
   Addison-Wesley
   ISBN 0201342979
   1998
   508 Seiten


* Die Java2 Fibel

   Ralf K�nel
   Addison-Welsey
   ISBN 3827314100
   1999
   442 Seiten


* Datenbanken und Java. JDBC, SQLJ und ODMG

   Gunter Saake, Kai-Uwe Sattler
   dpunkt-Verlag, Heidelberg
   2000
   ISBN: 3932588541


* Java Servlet Programming

   Jason Hunter, William Crawford
   O'Reilly
   ISBN 156592391X
   1988
   510 Seiten


* Komponenten in Java: Einsatz und Entwicklung von JavaBeans
   mit VisualAge for Java

   Claudia Piemont
   dpunkt-Verlag
   ISBN 3932588215
   1999
   347 Seiten


* Design mit Java. Bessere Applets und Anwendungen

   Peter Coad, Mark Mayfield
   Markt und Technik
   ISBN: 3827295866
   1999
   301 Seiten


englischsprachig, aber auch gut:

* Effective Java, Programming Language Guide

   Joshua Bloch
   The Java Series
   Addison-Wesley
   ISBN 0201310058


* Image Processing in Java

   Douglas A. Lyon
   Prentice Hall
   ISBN 0-13-97457707
   1999
   532 Seiten


5. Themenverwandte Internet Ressourcen
======================================

5.1. WWW-Sites
--------------

Deutschsprachige:

Java:
  + Immer aktuelle archivierte Version dieser Text FAQ
    <URL:ftp://rtfm.mit.edu/pub/usenet-by-group/
    de.answers/de/comp-lang-java/faq>

  + HTML Version dieser FAQ von Uwe Plonus
    <URL:http://de.geocities.com/uweplonus/faq/>

  + deutsche Java-FAQ von Markus Reitz (de.comp.lang.java)
    <URL:http://www.dclj.de/>
    <URL:http://www.geocities.com/SiliconValley/Foothills/5270/>

  + Java-Einfuehrung von Hubert Partl (BOKU Wien)
    <URL:http://www.boku.ac.at/javaeinf/>

  + Go to Java 2 von Guido Krueger (Addison Wesley Verlag)
    <URL:http://www.javabuch.de/>
    <URL:http://www.gkrueger.com/>

  + Java ist auch eine Insel von Christian Ullenboom
    <URL:http://java-tutor.com/>

  + Java Dokumentation von Brit Schroeter und Johann Plank
    <URL:http://www.selfjava.de/>

  + Liste weiterer Links, zusammengestellt von Ralf Geschke (Uni Koeln)
    <URL:http://infosoc.uni-koeln.de/akademie/java/>


HTML, XHTML:
  <URL:http://www.teamone.de/selfhtml/>
  <URL:http://www.boku.ac.at/htmleinf/>
  <URL:http://art2.ph-freiburg.de/HTML-Tutor/>
  <URL:http://www.netandmore.de/faq/>

XML:
  <URL:http://www.mintert.com/xml/>
  <URL:http://www.boku.ac.at/htmleinf/xmlkurz.html>

WAP und WML:
  <URL:http://www.boku.ac.at/htmleinf/wein.html>
  <URL:http://allnetdevices.com/faq/>


Englischsprachige:

Java:
  + Java Online-Doku der Firma Sun
    <URL:http://java.sun.com/docs/>

  + Java Tutorial der Firma Sun
    <URL:http://java.sun.com/docs/books/tutorial/index.html>

  + Java FAQ von Eliotte Rusty Harold
    <URL:http://sunsite.unc.edu/javafaq/javafaq.html>

  + Java Programmers FAQ von Peter van der Linden
    <URL:http://www.afu.com/javafaq.html>

  + Java Glossary von Roedy Green
    <URL:http://mindprod.com/gloss.html>

  + Thinking in Java von Bruce Eckel
    <URL:http://www.BruceEckel.com/javabook.html>

  + Java Tutorial von Prof. Baldwin
    <URL:http://www.phrantic.com/scoop/toc.htm>

  + Swing FAQ von Linda Radecke
    <URL:http://www.jalice.net/textfaq.htm>
    <URL:http://www.jalice.net/tablefaq.htm>
    <URL:http://www.jalice.net/componentfaq.htm>

  + Tips zu Java von Marco Schmidt
    <URL:http://jiu.sourceforge.net/javatips.html>

HTML, XML, XHTML u.a.:
  <URL:http://www.w3.org/>

WAP, WML:
  <URL:http://www.wapforum.org/>


Anmerkung: Diese Liste ist meine subjektive Auswahl und stellt
keinen Anspruch auf Vollstaendigkeit oder Objektivitaet.


5.2. Newsgroups
---------------

  <news:comp.lang.java.3d>
  <news:comp.lang.java.advocacy>
  <news:comp.lang.java.beans>
  <news:comp.lang.java.corba>
  <news:comp.lang.java.databases>
  <news:comp.lang.java.gui>
  <news:comp.lang.java.help>
  <news:comp.lang.java.machine>
  <news:comp.lang.java.programmer>
  <news:comp.lang.java.security>
  <news:comp.lang.java.softwaretools>


5.3. Mailinglisten
------------------

  <mailto:java-linux@java.blackdown.org>
  <mailto:nbusers@netbeans.org>


6. JavaScript Internet Ressourcen.
==================================

6.1 WWW-Sites

    <URL:http://www.teamone.de/selfhtml/>
    <URL:http://www.dcljs.de/>


6.2. Newsgroups

  <news:de.comp.lang.javascript>


7. Credits
==========
Folgende Personen waren an der Erstellung der FAQ beteiligt:

Werner Baumann,
Gerhard Bloch,
Frank Buss,
Paul Ebermann,
Alexander Elsholz,
Martin Erren,
Uwe G�nther,
Erwin Hoffmann,
Ingo R. Homann,
Ulf J�hrig,
Christian Kaufhold,
Georg Lipitsch,
Peter Luschny,
Stephan Menzel,
Alexander Merkelbach,
Michael Paap,
Hubert Partl,
Achim Peters,
Uwe Plonus,
Sascha Raabe,
Markus Reitz,
Aljoscha Rittner,
Wolfram R�haak,
Joachim Sauer,
Wolfgang Schirmer,
Marco Schmidt,
Michael Schmidt,
Karsten Schulz,
Roger Schuster,
Jochen Theodorou,
Tobias Vogele,
Christian Wederhake

(in alphabetischer Reihenfolge).

Die Version 1.0 dieser FAQ baut auf den FAQs von Hubert Partl,
Markus Reitz und Michael Schmidt auf.

Kritik und Verbesserungsvorschl�ge an der FAQ bitte direkt an den
Autor oder in die Newsgroup mit dem Tag [FAQ] im Subject.

User Contributions:

Comment about this article, ask questions, or add new information about this topic:


[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
uwe@cscc.de (Uwe Guenther)





Last Update March 27 2014 @ 02:11 PM