home *** CD-ROM | disk | FTP | other *** search
Text File | 2004-05-14 | 183.1 KB | 5,142 lines |
- Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news2.telebyte.nl!news.newsland.it!fu-berlin.de!uni-berlin.de!not-for-mail
- From: uwe@cscc.de (Uwe Guenther)
- Newsgroups: de.comp.lang.java,news.answers,de.answers
- Subject: FAQ der Newsgroup de.comp.lang.java Version 1.41 vom 14.05.2004
- Supersedes: <de/comp-lang-java/faq/127@cscc.de>
- Followup-To: de.comp.lang.java
- Date: 14 May 2004 04:00:09 +0200
- Organization: Java FAQ Enterprices Inc. http://www.cscc.de ;-)
- Lines: 5117
- Sender: root@mutter.family.local
- Approved: news-answers-request@MIT.EDU
- Expires: 28 May 2004 00:00:00 +0200
- Message-ID: <de/comp-lang-java/faq/128@cscc.de>
- Content-Type: text/plain; charset=iso-8859-1
- Content-Transfer-Encoding: 8bit
- X-Complaints-To: http://news.individual.net/abuse.html
- X-Trace: news.uni-berlin.de /5mtFYP9+8j7TuBYm0yvLAed635IePA9iAWVWvEnWqGE3WQVk=
- Summary: This posting describes what every reader of
- de.comp.lang.java ought to know about the Java programming
- language. It's in German, like the newsgroup.
- X-Orig-Path: not-for-mail
- X-Disclaimer: Approval for *.answers is based on form, not content.
- Xref: senator-bedfellow.mit.edu news.answers:271229 de.answers:10475
-
- Archive-name: de/comp-lang-java/faq
- Posting-Frequency: weekly (Friday)
- Last-modified: 2004-03-26
- Version: 1.41
- 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: 28 May 2004 00:00:00 CEST
- Tab-Width: 4
- Page-Width: 74
-
- FAQ (Frequently Asked Questions) der Newsgroup de.comp.lang.java v1.41
- =========================================================================
-
- 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. Wie kann man auf programmnahe Resourcen (Button-images,
- local String properties,...) zugreifen, ohne absolut oder
- relativ zu user.dir adressieren zu mⁿssen (ich will das
- ganze auch in ein jar packen k÷nnen)?
-
-
- 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. Wie kann man auf programmnahe Resourcen (Button-images,
- local String properties,...) zugreifen, ohne absolut oder relativ
- zu user.dir adressieren zu mⁿssen (ich will das ganze auch in ein
- jar packen k÷nnen)?
- Autor: Martin Erren
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 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 Resourcen nicht zu empfehlen.
-
- [Hier fehlt die Begrⁿndung]
-
-
-
-
- 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.setColor(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 ±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 ±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.
-