home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / de / comp-lang-java / faq
Encoding:
Text File  |  2004-05-14  |  183.1 KB  |  5,142 lines

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news2.telebyte.nl!news.newsland.it!fu-berlin.de!uni-berlin.de!not-for-mail
  2. From: uwe@cscc.de (Uwe Guenther)
  3. Newsgroups: de.comp.lang.java,news.answers,de.answers
  4. Subject: FAQ der Newsgroup de.comp.lang.java Version 1.41 vom 14.05.2004
  5. Supersedes: <de/comp-lang-java/faq/127@cscc.de>
  6. Followup-To: de.comp.lang.java
  7. Date: 14 May 2004 04:00:09 +0200
  8. Organization: Java FAQ Enterprices Inc. http://www.cscc.de ;-)
  9. Lines: 5117
  10. Sender: root@mutter.family.local
  11. Approved: news-answers-request@MIT.EDU
  12. Expires: 28 May 2004 00:00:00 +0200
  13. Message-ID: <de/comp-lang-java/faq/128@cscc.de>
  14. Content-Type: text/plain; charset=iso-8859-1
  15. Content-Transfer-Encoding: 8bit
  16. X-Complaints-To: http://news.individual.net/abuse.html
  17. X-Trace: news.uni-berlin.de /5mtFYP9+8j7TuBYm0yvLAed635IePA9iAWVWvEnWqGE3WQVk=
  18. Summary: This posting describes what every reader of
  19.          de.comp.lang.java ought to know about the Java programming
  20.          language. It's in German, like the newsgroup.
  21. X-Orig-Path: not-for-mail
  22. X-Disclaimer: Approval for *.answers is based on form, not content.
  23. Xref: senator-bedfellow.mit.edu news.answers:271229 de.answers:10475
  24.  
  25. Archive-name: de/comp-lang-java/faq
  26. Posting-Frequency: weekly (Friday)
  27. Last-modified: 2004-03-26
  28. Version: 1.41
  29. 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
  30. Expires: 28 May 2004 00:00:00 CEST
  31. Tab-Width: 4
  32. Page-Width: 74
  33.  
  34.   FAQ (Frequently Asked Questions) der Newsgroup de.comp.lang.java v1.41
  35. =========================================================================
  36.  
  37. Inhalt:
  38. -------
  39.  
  40. 1. Allgemeines
  41.  
  42.    1.1. Allgemeine Hinweise zum Posten
  43.    1.2. Worum geht es in dieser Newsgroup?
  44.    1.3. Wie kommen hΣufig gestellte Fragen in diese FAQ?
  45.    1.4. Wie kommen die Bugs aus der FAQ?
  46.    1.5. TAGS-Konventionen zu einem einheitlichen Aussehen
  47.    1.6. Ich bekam als Antwort auf meine Frage eine seltsame Buchstaben-
  48.         kombination zugeschickt. Was ist das und wie kann ich es lesen?
  49.  
  50.  
  51. 2. Was man ⁿber Java wissen sollte
  52.  
  53.    2.1. Was ist Java?
  54.    2.2. Verwandtschaft von Java mit anderen Sprachen?
  55.    2.3. WebBrowser und Java
  56.    2.4. Erste Schritte in Java
  57.    2.5. Ich habe das HelloWorld-Programm aus meinem Java-Buch
  58.         abgeschrieben, aber es funktioniert nicht. :-(
  59.  
  60.  
  61. 3. HΣufig gepostete Fragen
  62.  
  63.     3.1. [LANG] - Die Sprache Java.
  64.         3.1.1. Gibt es in Java keine Zeiger wie in C++?
  65.         3.1.2. Warum ist Referenz nicht gleich Referenz?
  66.         3.1.3. Wie werden in Java Funktionsparamter ⁿbergeben, by value
  67.                oder by reference?
  68.         3.1.4. Warum gibt es in Java keine Destruktoren wie in C++?
  69.         3.1.5. Warum funktioniert die equals Methode nicht?
  70.         3.1.6. Wenn ich eigene Objekte mit einer Hashtable/HashMap
  71.                verwalte, kommt es zu sonderbaren Effekten. Wieso?
  72.         3.1.7. Was bedeutet das Schlⁿsselwort final?
  73.         3.1.8. Warum wird der dynamische Parametertyp bei ⁿberladenen
  74.                Funktionen nicht beachtet?
  75.         3.1.9. Was bedeutet super()?
  76.         3.1.10. Was sind anonyme Arrays?
  77.         3.1.11. Gibt es in Java einen PrΣ-Prozessor wie in C++?
  78.         3.1.12. Existiert der const Modifizierer von C++ auch in Java?
  79.         3.1.13. Wie kann man Referenzen von ▄bergabeparametern Σndern?
  80.         3.1.14. Wie erzeuge ich eine  tiefe  Kopie eines Objektes mit
  81.                 m÷glichst wenig Aufwand?
  82.         3.1.15. Wie kann ich in Java eine dem Programmierer unbekannte
  83.                 Anzahl gleichartiger Objekte erzeugen und ihnen passende
  84.                 Namen zuweisen, also label1, label2 usw.?
  85.         3.1.16. Wie kann ich den Typ enum aus C++ in Java umsetzen?
  86.         3.1.17. Kann man Mehrfachvererbung mit Java simulieren?
  87.         3.1.18. Wie realisiere ich eine variable Parameterliste?
  88.         3.1.19. Wie realisiere ich eine Methodenauswahl nach den
  89.                 dynamischen Parametertypen?
  90.         3.1.20. Sind Methoden in Java immer virtuell?
  91.         3.1.21. Ich stosse ab und zu auf den Begriff "Wrapper-Klassen".
  92.                 K÷nnte mir jemand erklΣren was das ist?
  93.         3.1.22. Warum ist private nicht privat?
  94.  
  95.  
  96.     3.2. [STRING] - Strings.
  97.         3.2.1. Wie vergleiche ich zwei Strings in Java?
  98.         3.2.2. Wie wandle ich einen String in einen Integer?
  99.         3.2.3. Wie wandle ich einen Integer in einen String um?
  100.         3.2.4. Wie wandle ich einen Integer in einen HexString um?
  101.         3.2.5. Wie kann ich eine Zahl formatieren und wie lege ich die
  102.                Anzahl der Nachkommastellen fest?
  103.         3.2.6. Wie kann ich ein Datum formatieren?
  104.         3.2.7. Wie kann ich in einem String oder StringBuffer mehrere
  105.                Zeichen suchen und ersetzen?
  106.         3.2.8. Gibt es regulΣre Ausdrⁿcke in Java (regular expressions)?
  107.  
  108.  
  109.     3.3. [IO] - Eingabe/Ausgabe, Streams, etc.
  110.         3.3.1. Verlangsamt Serialisierung mein Programm?
  111.         3.3.2. Wie kann ich rekursiv einen Verzeichnisbaum abarbeiten?
  112.         3.3.3. Wie kann ich aus Dateien zeilenweise lesen?
  113.         3.3.4. Wie kann ich Exponentialzahlen (z.B. 1.09E+008) aus einer
  114.                Datei lesen?
  115.         3.3.5. Wie kann ich mit Java Dateien kopieren?
  116.         3.3.6. Wie kann man auf programmnahe Resourcen (Button-images,
  117.                local String properties,...) zugreifen, ohne absolut oder
  118.                relativ zu user.dir adressieren zu mⁿssen (ich will das
  119.                ganze auch in ein jar packen k÷nnen)?
  120.  
  121.  
  122.     3.4. [NET] - Netzwerk.
  123.         3.4.1. Wie kann ich einen Ping in Java realisieren?
  124.  
  125.  
  126.     3.5. [AWT] - Abstract Window Toolkit.
  127.         3.5.1. Wenn ich einen Listener bei mehreren Buttons anmelde, wie
  128.                kann ich dann unterscheiden, welcher gedrⁿckt wurde?
  129.         3.5.2. Kann ich ein Fenster (Frame/JFrame) maximieren?
  130.         3.5.3. Wie tausche ich die Kaffeetasse im blauen Balken aus?
  131.  
  132.  
  133.     3.6. [SWING] - Swing, das bevorzugte GUI.
  134.         3.6.1. Wie mache ich globale Font-─nderung fⁿr meine Komponenten?
  135.         3.6.2. Wie kann ich bei der Eingabe in ein JTextField die Anzahl
  136.                der eingebbaren Zeichen beschrΣnken?
  137.         3.6.3. Wie setze ich den Cursor an den Anfang der JTextArea?
  138.         3.6.4. Wie scrolle ich an das Ende der JTextArea?
  139.         3.6.5. Wie bekomme ich es hin, das der Benutzer in meiner JTable
  140.                keine Eingaben tΣtigen kann?
  141.         3.6.6. Wie bekomme ich eine horizontale ScrollBar bei JTable?
  142.         3.6.7. Wie scrolle ich ans Ende von JTable?
  143.         3.6.8. Wie verhindere ich ein reordering der Spalten bei JTable?
  144.         3.6.9. Wie verhindere ich ein Resizen der Spalten bei JTable?
  145.         3.6.10. Wie Σndere ich die Hintergrundfarbe von JScrollPane?
  146.         3.6.11. Wie kann ich ein JLabel dazu bringen, seinen Hintergrund
  147.                 zu fⁿllen?
  148.         3.6.12. Warum reagiert meine GUI nicht, wΣhrend eine lΣngere 
  149.                 Berechnung ausgefⁿhrt wird?
  150.  
  151.  
  152.     3.7. [APPLET] - Java-Applets und ihre Zusammenarbeit mit Browsern.
  153.         3.7.1. Welche JDK-Version sollte ich fⁿr Applets verwenden, die
  154.                m÷glichst allgemein lauffΣhig sein sollen?
  155.         3.7.2. Wie bekomme ich den Internet Explorer dazu, das Plugin
  156.                anstelle der integrierten JVM zu benutzen.
  157.         3.7.3. Was dⁿrfen unsignierte Applets nicht aus
  158.                Sicherheitsgrⁿnden?
  159.  
  160.  
  161.     3.8. [SERVER] - Servlets und andere Server-Implementierungen in Java.
  162.  
  163.  
  164.     3.9. [NONCORE] - Klassen/Packages, die ⁿber den Kern der Sprache
  165.                      hinausgehen, also Java3D etc.
  166.  
  167.     3.10. [OOP] - OOP-Konzepte und Patterns in Java.
  168.         3.10.1. Was bedeutet Vererbung im OO-Kontext?
  169.         3.10.2. Was bedeutet Aggregation im OO-Kontext?
  170.         3.10.3. Was bedeutet Assoziation ist OO-Kontext?
  171.         3.10.4. Was bedeutet Benutzung im OO-Kontext?
  172.         3.10.5. Worin liegen die Unterschiede zwischen abstrakten Klassen
  173.                 und Interfaces?
  174.         3.10.6. Was ist eine anonyme innere Klasse?
  175.         3.10.7. Was ist ein immutable Objekt?
  176.  
  177.  
  178.     3.11. [JDK] - Virtuelle Maschinen, alles ⁿber JDKs, deren
  179.                   Installation und Verwendung.
  180.         3.11.1. Was ist ein Java Development Kit (JDK)
  181.         3.11.2. Was ist ein Java Runtime Environment (JRE)
  182.         3.11.3. Was ist eine Java Virtual Machine (JVM)
  183.         3.11.4. Wie konfiguriere ich JDK1.3/1.4 unter Linux oder Unix?
  184.         3.11.5. Wie installiere und konfiguriere ich das jdk unter
  185.                 Windows 9x/Me/NT/2000 richtig?
  186.  
  187.  
  188.     3.12. [TOOLS] - Java-Zusatz-Tools, zum Beispiel IDEs, Build-Tools,
  189.                     Profiler, etc.
  190.         3.12.1. Welche IDE muss ich verwenden?
  191.         3.12.2. Wie kann man eine Java-Anwendung in eine EXE-Datei
  192.                 umwandeln?
  193.  
  194.  
  195.     3.13. [MATH] - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.
  196.         3.13.1. Warum rechnet Java falsch?
  197.         3.13.2. Wie runde ich eine Gleitkommazahl?
  198.                 Wie formatiere ich eine Gleitkommazahl?
  199.         3.13.3. Wie kann ich in Java Zufallszahlen im Bereich 0..n
  200.                 erzeugen?
  201.  
  202.  
  203.     3.14. [MISC] - Alles, was nicht in eine der anderen Rubriken pa▀t.
  204.         3.14.1. Ich komme mit dem import-Statement nicht klar, was mache
  205.                 ich falsch?
  206.         3.14.2. Warum gibt es Probleme bei final Werten in Verbindung mit
  207.                 elementaren Typen?
  208.         3.14.3. Was bedeuten "$" im Namen von Class-Files?
  209.         3.14.4. Wie lassen sich Bilder im Dateiformat XYZ laden oder
  210.                 speichern?
  211.         3.14.5. Was geht nicht mit Java?
  212.         3.14.6. Wie kann ich in meinem Java-Programm ein HTML-Dokument
  213.                 anzeigen lassen?
  214.         3.14.7. Unter Windows werden in der Konsole (DOS-Eingabe-
  215.                  aufforderung) die Umlaute falsch ausgegeben. Wie kann
  216.                  ich das korrigieren?
  217.  
  218.  
  219.     3.15. [ERROR] - Fehlermeldungen.
  220.         3.15.1. Warum findet Java den Konstruktor nicht?
  221.         3.15.2. Warum bekomme ich eine "NoClassDefFoundError"
  222.                 Fehlermeldung beim Starten von java?
  223.         3.15.3. Warum bekomme ich eine "Couldn't read <Name>"
  224.                 Fehlermeldung beim Kompilieren mit javac?
  225.         3.15.4. Warum bekomme ich eine "class <Name> must be defined in
  226.                 a file called <Name>" Fehlermeldung  beim Kompilieren
  227.                 von javac?
  228.         3.15.5. Warum wird beim Zugriff auf ein korrekt initialisiertes
  229.                 Objekt-Array eine NullPointerException geworfen?
  230.         3.15.6. Warum bekomme ich eine NullPointerException, wenn ich
  231.                 versuche, auf Methoden oder Attribute von in einem Array
  232.                 gespeicherten Objekten zuzugreifen?
  233.         3.15.7. Warum meckert der Compiler bei nicht initialisierten
  234.                 final Variablen?
  235.         3.15.8. Was hat die Compilerfehlermeldung "... is deprecated" zu
  236.                 bedeuten?
  237.  
  238.  
  239.     3.16. [ClassLoader] - Alles ⁿber Classloader
  240.         3.16.1 Wie funktionieren Classloader?
  241.         3.16.2 Warum macht der Classloader im Servlet-Container Probleme?
  242.                Warum funktioniert das Einlesen von Ressourcen ueber den
  243.                Classloader bei mir nicht?
  244.         3.16.3 Wie lade ich eine Klasse neu?
  245.         3.16.4 Wie baue ich einen Plugin-Mechanismus?
  246.         3.16.5 Gibt's dazu auch Beispielcode?
  247.         3.16.6 ClassLoader Ressourcen zu 3.16.1 bis 3.16.5
  248.  
  249.  
  250. 4. Bⁿcher zum Thema Java
  251.  
  252.     4.1. Kann mir jemand gute Literatur zum Thema Java empfehlen?
  253.  
  254.  
  255. 5. Themenverwandte Internet Ressourcen
  256.  
  257.     5.1 WWW-Sites
  258.     5.2 Newsgroups
  259.     5.3 Mailinglisten
  260.  
  261.  
  262. 6. JavaScript Internet Ressourcen.
  263.  
  264.     6.1 WWW-Sites
  265.     6.2 Newsgroups
  266.  
  267.  
  268. 7. Credits
  269. _____________________________________________________________________
  270.  
  271. 1. Allgemeines
  272. ==============
  273.  
  274. 1.1. Allgemeine Hinweise zum Posten
  275. -----------------------------------
  276. Wenn du neu im Usenet bist, solltest du auf jeden Fall die Texte in
  277. der Newsgroup <news:de.newusers.infos> lesen. Du findest sie auch im
  278. WWW auf <URL:http://www.kirchwitz.de/~amk/dni/>. In diesen Texten
  279. erhΣlt man einen ▄berblick ⁿber die im Usenet ⁿblichen Regeln
  280. ("Netiquette"). Auf diese Weise lassen sich die meisten AnfΣnger-
  281. fehler verhindern und man vermeidet, gleich fⁿr sein erstes Posting
  282. wegen formaler Fehler angeschnauzt zu werden. Falls du Fragen zu den
  283. Regeln im Usenet hast, stelle sie bitte in der Newsgroup
  284. <news:de.newusers.questions>.
  285.  
  286. Weitere Links zum Thema:
  287.  
  288.     <URL:ftp://rtfm.mit.edu/pub/usenet/de.answers/de-newusers/>
  289.     <URL:http://learn.to/quote/>
  290.  
  291.  
  292. 1.2. Worum geht es in dieser Newsgroup?
  293.      Autor: Markus Reitz
  294. ---------------------------------------
  295. In der Newsgroup <news:de.comp.lang.java> sollen Probleme und L÷sungen,
  296. die sich im Zusammenhang mit der Programmiersprache Java ergeben,
  297. diskutiert werden. Die Newsgroup beschΣftigt sich nur mit der Sprache
  298. Java! JavaScript oder herstellerspezifische Implementierungen (z.B.
  299. Microsoft J++) besitzen eigene Newsgroups, in denen diese
  300. spezifischen Probleme und L÷sungen diskutiert werden. Neben der
  301. Newsgroup <news:de.comp.lang.java> gibt es noch weitere (vor allem
  302. englischsprachige) Newsgroups, die sich mit der Programmiersprache
  303. Java beschΣftigen. Siehe auch den Abschnitt "Themenverwandte
  304. Newsgroups".
  305.  
  306. 1.3. Wie kommen hΣufig gestellte Fragen in diese FAQ?
  307.      Autor: Uwe Gⁿnther
  308. -----------------------------------------------------
  309. Nachdem man festgestellt hat, dass man in einem bestimmten Zyklus die
  310. gleiche Frage immer wieder mit der gleichen Antwort beantworten muss -
  311. nur weil die Unis ihren Lehrplan mal wieder geΣndert haben, in der c't
  312. mal wieder ein "Wie programmiere ich ein Applet"-Kurs unter die Leute
  313. gebracht wurde oder aus welchen Grⁿnden auch immer - sollte man einen
  314. neuen Thread mit dem
  315.  
  316.     Subject: [FAQ] Neue Frage: <Frage>
  317.  
  318. beginnen.
  319.  
  320. Der Body dieser Nachricht sollte folgendes Format besitzen:
  321.  
  322. --Schnipp--
  323. Frage: <Frage>
  324.  
  325. Antwort: <Antwort>
  326.  
  327. Beispiel: <Code>
  328. --Schnapp--
  329.  
  330. Wobei der Text in spitzen Klammern, dein Part ist. Die ZeilenlΣnge darf
  331. 74 Zeichen nicht ⁿberschreiten. Der Code sollte die Code Conventions von
  332. Sun einhalten - wenn du nicht weisst was das ist, solltest du besser
  333. keine FAQ schreiben. Der gesamte Text darf keine Tabs enthalten und bei
  334. Bedarf gegen 4 Leerzeichen ersetzt werden. Es ist von grossem Vorteil
  335. wenn der Beispiel-Code kompilierbar ist. Das steigert die QualitΣt der
  336. FAQ ungemein.
  337.  
  338. Nachdem der Thread dann von den Regulars und den anderen Lesern von
  339. de.comp.lang.java gebⁿhrend behandelt wurde und etwaige Probleme
  340. ausgerΣumt wurden, muss die Endfassung des Textes an die im Header dieser
  341. FAQ angegebene e-mail Adresse des FAQ-Maintainers von de.comp.lang.java
  342. gesendet werden. Dabei ist es erwⁿnscht die Rubrik, oder gleich die
  343. zukⁿnftige Fragennummerierung mit anzugeben. Weiterhin muss die
  344. Message-ID mit angegeben werden, damit der FAQ-Maintainer ⁿberprⁿfen kann
  345. ob er nicht von irgendjemanden vereimert wird. ;-)
  346.  
  347.  
  348. 1.4. Wie kommen die Bugs aus der FAQ?
  349.      Autor: Uwe Gⁿnther
  350. -------------------------------------
  351. Nachdem man festgestellt hat, dass die FAQ einen Fehler hat, kann man
  352. diesen dem FAQ-Maintainer unter Angabe eines Workarounds direkt
  353. mitteilen.
  354.  
  355.  
  356. 1.5. TAGS-Konventionen zu einem einheitlichen Aussehen
  357.      Autor: Markus Reitz
  358. --------------------------------------------------------
  359. Neben den schon weiter oben genannten RatschlΣgen, die allgemeine
  360. Anmerkungen zum Posten in Newsgroups darstellen, folgen nun einige
  361. spezifische Anmerkungen zur Schreibweise des Subjects in der
  362. Newsgroup <news:de.comp.lang.java>. Vor einiger Zeit wurde die
  363. Einfⁿhrung sogenannter Tags vorgeschlagen, die die ▄bersichtlichkeit
  364. steigern sollen. Hintergrund ist die einfache Idee, den Inhalt des
  365. Postings durch ein eindeutiges Schlⁿsselwort, das Tag, zu
  366. charakterisieren. Mit einem entsprechend konfigurierten Newsreader ist
  367. es dann m÷glich, sich solche Nachrichten hervorheben zu lassen, wodurch
  368. man direkt auf einen Blick Postings beispielsweise zum Thema Swing
  369. ⁿberschauen kann. Tags werden an den Anfang des Subjects, in eckigen
  370. Klammern eingeschlossen, geschrieben. Damit Einheitlichkeit gewahrt
  371. wird, sollten die folgenden Tags verwendet werden. Wenn jeder seine
  372. eigenen Tags spezifizieren wⁿrde, wΣre die Einheitlichkeit verloren und
  373. es wⁿrde genau-soviel Chaos wie vorher herrschen. Deshalb an dieser
  374. Stelle die Bitte, sich an die Vorgaben zu halten. Bei
  375. ─nderungsvorschlΣgen bitte in die Newsgroup zur Diskussion posten und
  376. bei Akzeptanz in der Newsgroup werden die VorschlΣge an dieser Stelle
  377. in die FAQ aufgenommen.
  378.  
  379. Liste der Tags in <news:de.comp.lang.java>:
  380.  
  381. Tags fⁿr Fragen:
  382.  
  383.     [LANG]
  384.     - Frage bezⁿglich der Sprache Java.
  385.  
  386.     [STRING]
  387.     - Fragen die unmittelbar mit Strings zu tun haben.
  388.  
  389.     [IO]
  390.     - Frage bezⁿglich Eingabe/Ausgabe, Streams, etc. in Java.
  391.  
  392.     [NET]
  393.     - Frage bezⁿglich Netzwerk.
  394.  
  395.     [AWT]
  396.     - Frage bezⁿglich AWT.
  397.  
  398.     [SWING]
  399.     - Frage bezⁿglich Swing.
  400.  
  401.     [APPLET]
  402.     - Frage zu Java-Applets und ihre Zusammenarbeit mit Browsern.
  403.  
  404.     [SERVER]
  405.     - Frage zu Servlets und anderen Server-Implementierungen in Java.
  406.  
  407.     [NONCORE]
  408.     - Fragen zu Klassen/Packages, die ⁿber den Kern der Sprache
  409.       hinausgehen, also Java3D etc.
  410.  
  411.     [OOP]
  412.     - Frage bezⁿglich OOP-Konzepten und Patterns in Java.
  413.  
  414.     [JDK]
  415.     - Frage zu virtuelle Maschinen, alles ⁿber JDKs und deren
  416.       Installation und Verwendung.
  417.  
  418.     [TOOLS]
  419.     - Frage zu einem Java-Zusatz-Tool, zum Beispiel IDEs, Build-Tools,
  420.       Profiler, etc.
  421.  
  422.     [MATH]
  423.     - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.
  424.  
  425.     [MISC]
  426.     - Alles, was nicht in eine der anderen Rubriken pa▀t.
  427.  
  428.     [ERROR]
  429.     - Fragen zu Fehlermeldungen.
  430.  
  431.     [OT]
  432.     - Alles was hochgrading off-topic ist und nicht direct mit Java zu
  433.       tun hat. ;-)
  434.  
  435.  
  436. Tags "nicht"-Fragen:
  437.  
  438.     [INFO]
  439.     - Allgemeine Informationen, z.B. Links auf Webseiten
  440.  
  441.     [DISCUSSION]
  442.     - Diskussion zu einem Java-spezifischen Thema
  443.  
  444.     [ANNOUNCE]
  445.     - Vorstellung neuer Software
  446.  
  447.     [PROST]
  448.     - Darf nur von Regulars verwendet werden, die wissen was sie tun. ;-)
  449.  
  450.  
  451. 1.6. Ich bekam als Antwort auf meine Frage eine seltsame Buchstaben-
  452.      kombination zugeschickt. Was ist das und wie kann ich es lesen?
  453.      Autor: Stephan Menzel
  454. --------------------------------------------------------------------
  455. Diese Kombination ist eine sogenannte Message-ID und bezeichnet einen
  456. Usenetartikel eindeutig.
  457.  
  458. Vorgehensweise bei Message-ID-Angaben:
  459.  
  460. (a) man hat einen Newsreader, der damit umgehen kann:
  461.     - einfach draufklicken.
  462.  
  463. (b) Wenn man Opera ab Version 6 verwendet, kann man in der Adressleiste
  464. einfach "r msgid:a2kpac.14g.1@aljoscha-rittner.de" eingeben und gelangt
  465. zur entsprechenden Seite von Google Groups.
  466.  
  467. (c) ansonsten: http://groups.google.com,
  468. dann msgid:a2kpac.14g.1@aljoscha-rittner.de eingeben.
  469.  
  470. (d) Wenn man gerne URLs bastelt:
  471. http://groups.google.com/groups?q=msgid:a2kpac.14g.1@aljoscha-rittner.de
  472.  
  473. (e) oder http://groups.google.com/advanced_group_search dann Msg-ID bei
  474. "Beitrags-ID" eingeben.
  475.  
  476.  
  477.  
  478. 2. Was man ⁿber Java wissen sollte
  479. ==================================
  480.  
  481. 2.1. Was ist Java
  482.      Autor: Markus Reitz
  483. ------------------------
  484. Zuersteinmal: Java ist nicht JavaScript. JavaScript ist eine Sprache,
  485. die federfⁿhrend von der Firma Netscape entwickelt wurde, um die
  486. Inhalte von Webseiten dynamischer und interaktiver zu gestalten.
  487. JavaScript-Programme werden in den HTML-Quelltext der Seite
  488. eingebettet und vom Browser interpretiert und ausgefⁿhrt. Zwar macht
  489. JavaScript viele Anleihen bei Java, ist aber bei weitem nicht so
  490. flexibel.
  491.  
  492.     Die deutsche Newsgroup zu JavaScript findet man unter:
  493.  
  494.         <news:de.comp.lang.javascript>
  495.  
  496.     Die Website von de.comp.lang.javascript ist unter folgendem
  497.     Link zu finden:
  498.  
  499.         <URL:http://www.dcljs.de/>
  500.  
  501. Java wurde von der Firma SUN Microsystems mit dem Ziel entwickelt, eine
  502. moderne, objektorientierte Sprache zu schaffen. Durch das Ziel der
  503. PlattformunabhΣngigkeit ist Java vor allem im Zusammenhang mit der
  504. Entwicklung von Web-Applikationen im Internet eine der am hΣufigsten
  505. verwendeten Sprachen. Doch Java beschrΣnkt sich nicht nur auf das
  506. Erstellen von Effekten fⁿr die Webseite, Java ist eine ausgewachsene
  507. Programmiersprache, mit der man alle anstehenden Probleme l÷sen kann.
  508. Die Syntax der Sprache ist an die von C++ angelehnt, Schlⁿsselw÷rter
  509. sind verΣndert bzw. in der Bedeutung erweitert worden, bestimmte
  510. Features von C++ wurden zugunsten der ▄bersichtlichkeit bzw. Sicherheit
  511. nicht in Java verwendet. Java Programme liegen im sogenannten Bytecode
  512. vor, der Maschinencode fⁿr einen fiktiven Prozessor, der von der VM, der
  513. virtuellen Maschine, ausgefⁿhrt wird. Durch die Verwendung des Bytecodes
  514. wird die PlattformunabhΣngigkeit von Java garantiert - dieser Vorteil
  515. wird aber durch die, im Vergleich zu anderen Sprachen wie C++, wesentlich
  516. langsamere Ausfⁿhrungsgeschwindigkeit bezahlt.
  517.  
  518.  
  519. 2.2. Verwandtschaft von Java mit anderen Sprachen?
  520.      Autor: Markus Reitz
  521. -------------------------------------------------
  522. Java bietet eine Reihe von neuen Features, orientiert sich aber auch
  523. an etablierten Sprachen wie C++, Smalltalk oder Objective-C.
  524. Prinzipien aus diesen Sprachen wurden ⁿbernommen und teilweise
  525. erweitert. Die folgende Tabelle gibt einen kleinen ▄berblick ⁿber
  526. Features von Java, die aus anderen Sprachen quasi "entliehen" wurden.
  527.  
  528.                                  |-----|-----------|-------------|
  529.                                  | C++ | Smalltalk | Objective-C |
  530. |--------------------------------|-----|-----------|-------------|
  531. | Primitive Datentypen           |  *  |           |             |
  532. |--------------------------------|-----|-----------|-------------|
  533. | Universelle Basisklasse Object |     |     *     |             |
  534. |--------------------------------|-----|-----------|-------------|
  535. | Garbage Collection             |     |     *     |             |
  536. |--------------------------------|-----|-----------|-------------|
  537. | Konstruktoren                  |  *  |           |             |
  538. |--------------------------------|-----|-----------|-------------|
  539. | Statische Typen                |  *  |           |             |
  540. |--------------------------------|-----|-----------|-------------|
  541. | Bibliothek von Standardklassen |     |     *     |             |
  542. |--------------------------------|-----|-----------|-------------|
  543. | Interfaces                     |     |           |      *      |
  544. |--------------------------------|-----|-----------|-------------|
  545.  
  546. Im Vergleich zu C++ besitzt Java folgende Unterschiede:
  547.  
  548.   - noch keine Templates
  549.   - keine Operatorenⁿberladung
  550.   - kein prozeduraler Overhead
  551.   - keine Mehrfachvererbung von Klassen
  552.  
  553.  
  554. 2.3. WebBrowser und Java
  555.      Autor: Markus Reitz
  556. ------------------------
  557. Java zΣhlt immer noch zu den  jⁿngeren  Programmiersprachen und die
  558. Entwicklung verlΣuft in manchen Bereichen noch mit hoher
  559. Geschwindigkeit. Insbesondere Zusatz-APIs findet man inzwischen wie
  560. Sand am Meer und praktisch jede neue Version des JDK bietet
  561. Verbesserungen oder Erweiterungen der bestehenden APIs.
  562.  
  563. Dies wird insbesondere dann problematisch, wenn man Java-Applets
  564. schreiben m÷chte, die in den bekannten Web-Browsern von Netscape oder
  565. Microsoft laufen sollen. HΣufig werden aktuelle Features nur
  566. unzureichend oder gar nicht unterstⁿtzt. Deshalb sollte man folgendes
  567. beachten:
  568.  
  569.   - ─ltere Webbrowser unterstⁿtzen (im gⁿnstigsten Fall) nur die
  570.     Version 1.0 der Sprache
  571.   - Neuere Webbrowser unterstⁿtzen zumindest teilweise die
  572.     Sprachversion 1.1 (Netscape ab Version 4.04-J2, Microsoft
  573.     Internet-Explorer ab Version 4.0)
  574.  
  575. Um eine m÷glichst gro▀e Anzahl an Plattformen bedienen zu k÷nnen, mu▀
  576. man sich also am besten auf Features der Sprache beschrΣnken, die schon
  577. in der UrVersion vorhanden waren. Bei neueren Features lΣuft man
  578. Gefahr, da▀ Besitzer Σlterer Browser ausgeschlossen werden. Eine andere
  579. Alternative bietet die Verwendung des von SUN erhΣltlichen
  580. Java-Plug-In's. Dadurch werden Σltere Browserversionen mit den Features
  581. der aktuellen Java-Version aufgerⁿstet, wodurch es dann sogar m÷glich
  582. wird, Java 2 - Programme in Browsern ablaufen zu lassen, obwohl diese
  583. die neueste Version ursprⁿnglich noch gar nicht unterstⁿtzen. Das
  584. Plug-In ist auf der Homepage von SUN erhΣltlich, problematisch ist
  585. allerdings die Gr÷▀e. Es ist daher fraglich, ob Benutzer bereit sind,
  586. sich wegen eines kleinen Homepage-Effektes ein gro▀es Plug-In
  587. herunterzuladen. Sinn macht das Plug-In daher nur bei wirklich gr÷▀eren
  588. Programmen oder bei Programmen, die fⁿr den Einsatz im Intranet
  589. ausgerichtet sind.
  590.  
  591.  
  592. 2.4. Erste Schritte in Java
  593.      Autor: Markus Reitz
  594. ---------------------------
  595. Erfahrungen mit der Sprache Java zu sammeln ist nicht schwer. Sofern
  596. man einen Internetzugang hat, kann man sich die Sprachdefinition,
  597. Compiler etc. direkt von SUN besorgen. Es empfiehlt sich die Verwendung
  598. der Java-Implementierung von SUN, denn diese ist die Referenz fⁿr alle
  599. anderen Implementierungen und normalerweise die, die sich am aktuellsten
  600. Sprachstandard orientiert. L÷sungen von Microsoft oder Symantec haben
  601. den Nachteil, da▀ Features modifiziert oder gar nicht implementiert
  602. werden oder FΣhigkeiten hinzukommen, die der ursprⁿnglichen
  603. Sprachimplementation fehlen. Au▀erdem bietet das JDK (Java Development
  604. Kit) von SUN den Vorteil, da▀ es kostenlos verfⁿgbar ist. Nachteil:
  605. Compiler und Tools arbeiten kommandozeilenorientiert, d.h. man schreibt
  606. den Quellcode mit einem beliebigen Editor, speichert die Datei und fⁿhrt
  607. dann den Compiler aus. Bei Fehlern lΣdt man die Datei, korrigiert den
  608. Fehler und das ganze Spiel beginnt von vorne. Abhilfe schaffen IDEs
  609. (Integrated Development Environment), die das JDK steuern und Fehler
  610. und andere Meldungen direkt anzeigen, ohne da▀ der Quelltexteditor
  611. verlassen werden mu▀. Ein weiterer Vorteil von IDEs ist das Feature
  612. Syntax Highlighting, das die Schlⁿsselw÷rter der Sprache farblich
  613. hervorhebt und dadurch die ▄bersichtlichkeit steigert.
  614.  
  615. Bezugsquelle fⁿr das JDK: <URL:http://www.java.sun.com/j2se/>
  616.  
  617.  
  618. 2.5. Ich habe das HelloWorld-Programm aus meinem Java-Buch
  619.      abgeschrieben, aber es funktioniert nicht. :-(
  620.      Autor: Hubert Partl
  621. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  622. Newbie:
  623. Ich habe das HelloWorld-Programm aus meinem Java-Buch abgeschrieben,
  624. aber es funktioniert nicht. :-(
  625.  
  626. Oldie:
  627. Das ist schon richtig :-) so, das HelloWorld-Beispiel dient dazu,
  628. dass Du die typischen Anfaenger-Fehler kennenlernst und in Zukunft
  629. vermeiden kannst.
  630.  
  631. In diesem Fall kann ich nur raten: Du hast wahrscheinlich einen der
  632. folgenden typischen Newbie-Fehler gemacht:
  633.  
  634. * Du hast das Programm nicht genau genug abgeschrieben (Tippfehler,
  635. Gross-Kleinschreibung, Sonderzeichen, Leerstellen), lies doch die
  636. Fehlermeldungen und Korrekturhinweise, die der Compiler Dir gibt.
  637.  
  638.  
  639. * Du hast das Programm nicht unter dem richtigen Filenamen abgespeichert.
  640. Wenn die Klasse HelloWorld heisst, muss das File HelloWorld.java heissen,
  641. nicht helloworld.java und auch nicht HelloWorld.java.txt, im letzteren
  642. Fall versuch es mit
  643.  
  644.     notepad "HelloWorld.java"
  645.  
  646.  
  647. * Du hast beim Compiler nicht den kompletten Filenamen mit der Extension
  648. angegeben (wieder mit der richtigen Gross-Kleinschreibung):
  649.  
  650.    javac HelloWorld.java
  651.  
  652.  
  653. * Du hast bei der Ausfuehrung nicht den Klassennamen ohne die Extension
  654. angegeben (wieder mit der richtigen Gross-Kleinschreibung):
  655.  
  656.     java HelloWorld
  657.  
  658.  
  659. * In der Umgebungsvariable PATH ist das Directory, in dem sich die
  660. JDK-Software befindet, nicht neben den anderen Software-Directories
  661. enthalten, versuch
  662.  
  663.     set PATH=%PATH%;C:\jdk1.2\bin
  664.  
  665. oder wie immer das auf Deinem Rechner heissen muss.
  666.  
  667.  
  668. * Die Umgebungsvariable CLASSPATH ist (auf einen falschen Wert) gesetzt.
  669. Diese Variable sollte ueberhaupt nicht gesetzt sein, nur in seltenen
  670. Spezialfaellen und dann so, dass sie sowohl die Stellen enthaelt,
  671. wo die Java-Klassenbibliotheken liegen, als auch den Punkt fuer das
  672. jeweils aktuelle Directory.
  673.  
  674.  
  675. * Du hast den Compiler nicht in dem Directory bzw. Folder aufgerufen,
  676. in dem Du das Java-File gespeichert hast.
  677.  
  678.  
  679. * Du hast ein Applet als Applikation aufgerufen, oder umgekehrt.
  680. Applikatonen, die eine main-Methode enthalten, musst Du mit
  681.  
  682.     java Classname
  683.  
  684. aufrufen. Applets, die ein "extends Applet" oder "extends JApplet"
  685. enthalten, musst Du innerhalb eines geeigneten HTML-Files mit
  686.  
  687.     appletviewer xxxxx.html
  688.  
  689. oder mit Netscape oder Internet-Explorer aufrufen.
  690.  
  691.  
  692. Mehr darueber findest Du in meiner Java-Einfuehrung auf
  693.  
  694.     <URL:http://www.boku.ac.at/javaeinf/jein1.html#software>
  695.  
  696.  
  697. Aehnliche Hinweise findest Du im Java Glossary von Roedy Green auf
  698.  
  699.     <URL:http://mindprod.com/gloss.html>
  700.  
  701.  
  702.  
  703. 3. HΣufig gepostete Fragen
  704. ==========================
  705.  
  706.  
  707. 3.1. [LANG] - Frage bezⁿglich der Sprache Java.
  708. -----------------------------------------------
  709.  
  710. 3.1.1. Gibt es in Java keine Zeiger wie in C++?
  711.        Autor: Markus Reitz
  712. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  713. Im Prinzip gibt es ein Konstrukt, das den Zeigern anderer
  714. Programmiersprachen, wie zum Beispiel C++, sehr Σhnlich ist: die
  715. sogenannten Referenzen. Referenzen k÷nnen, im Vergleich zu Zeigern in
  716. C++, nicht manipuliert werden; die sogenannte Zeigerarithmetik, bei der
  717. man Zeiger auf beliebige Speicherinhalte zeigen lassen kann, wurde aus
  718. Sicherheitsgrⁿnden nicht in Java ⁿbernommen. Der Inhalt einer Referenz
  719. kann einer anderen Referenz zugewiesen werden, Referenzen k÷nnen
  720. miteinander verglichen werden. Wird in Java eine Objektvariable
  721. angelegt, so ist dies nichts weiter als ein Speicherplatz fⁿr eine
  722. Referenz fⁿr ein Objekt des angegebenen Typs. Der new-Operator erzeugt
  723. das eigentliche Objekt und liefert die Referenz darauf zurⁿck, die dann
  724. in der Objektvariablen gespeichert wird.
  725.  
  726.  
  727. 3.1.2. Warum ist Referenz nicht gleich Referenz?
  728.        Autor: Markus Reitz
  729. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  730.  
  731. Problem:
  732.  
  733. public class Test {
  734.     public static void main (String[] args) {
  735.         String a = "A";
  736.         String x = a;
  737.         System.out.println(x);
  738.         a = "B";
  739.         System.out.println(x);
  740.     }
  741. }
  742.  
  743. Die Ausgabe sollte doch eigentlich so aussehen:
  744.  
  745.     A
  746.     B
  747.  
  748. Denn die Variable x speichert doch eine Referenz auf den String a! Im
  749. ersten Fall hat a den Wert  A  und damit auch x, das ja auf diesen
  750. String verweist. Im zweiten Fall wird a geΣndert und damit mⁿ▀te sich
  751. doch auch eigentlich der Wert von x Σndern, weil x auf a verweist.
  752. Die Ausgabe, die das Programm liefert, ist jedoch:
  753.  
  754.     A
  755.     A
  756.  
  757. was eigentlich nicht in das Bild einer normalen Referenz passt.
  758.  
  759.  
  760. Ursache:
  761.  
  762. Der Fehler liegt darin begrⁿndet, da▀ a nicht der eigentliche String
  763. ist, sondern nur eine Referenz auf diesen String. Durch x = a
  764. referenzieren beide Variablen den selben String und durch a = "B"
  765. verweist a auf einen anderen neuen String mit dem Wert B. Dies Σndert
  766. jedoch nichts an der Referenz, die in x gespeichert ist. Somit ist die
  767. Ausgabe v÷llig korrekt.
  768.  
  769.  
  770.  
  771. 3.1.3. Wie werden in Java Funktionsparamter ⁿbergeben, by value
  772.        oder by reference?
  773.        Autor: Paul Ebermann
  774. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  775. Java kennt  (genauso wie C, aber im Gegensatz zu etwa Pascal) kein
  776. "Call by Reference". Wenn Objekte als Parameter verwendet werden, wird
  777. eben die Referenz "by Value" ⁿbergeben. Somit kann man zwar das Objekt
  778. (so es verΣnderbar ist) verΣndern, aber nicht die originale Variable,
  779. die als Parameter verwendet wurde.
  780.  
  781. Beispiel fⁿr Call by Reference:
  782. (Pascal - [Syntax bestimmt nicht korrekt])
  783.  
  784. program ReferenzTest(input, output);
  785.  
  786.   var
  787.   x, y : integer;
  788.  
  789.   procedure swap (var a: integer; var b: integer);
  790.     var
  791.     h : Integer;
  792.  
  793.   begin
  794.     h := a;
  795.     a := b;
  796.     b := h;
  797.   end;
  798.  
  799. begin
  800.   x := 1;
  801.   y := 2;
  802.   swap(x,y);
  803.   writeLn('x = ', x, ', y = ', y , '.');
  804. end.
  805.  
  806. Das Programm gibt am Ende x = 2 und y = 1 aus.
  807. In Java geht das nicht:
  808.  
  809. package de.dclj.faq;
  810. class CallByReferenceTest
  811. {
  812.     static void swap (int a, int b)
  813.     {
  814.         int h = a;
  815.         a = b;
  816.         b = h;
  817.     }
  818.  
  819.     public static void main(String[] test)
  820.     {
  821.         int x = 1;
  822.         int y = 2;
  823.         swap(x,y);
  824.         System.out.println("x = " + x + ", y = " + y);
  825.     }
  826. }
  827.  
  828. Zur Call-by-Reference-Simulation bietet sich
  829. die Verwendung von Arrays an - da diese Objekte sind,
  830. wird ja nur die Referenz ⁿbergeben.
  831.  
  832.  
  833. class CallByReferenceSimulation
  834. {
  835.     static void swap(int[] a, int[] b)
  836.     {
  837.         int h = a[0];
  838.         a[0] = b[0];
  839.         b[0] = h;
  840.     }
  841.  
  842.     public static void main(String[] test)
  843.     {
  844.         int[] x = {1};
  845.         int[] y = {2};
  846.         swap(x,y);
  847.         System.out.println("x = " + x[0] + ", y = " + y[0]);
  848.     }
  849. }
  850.  
  851. Einen etwas anderen Blickwinkel zu diesem Thema bietet die Webseite:
  852.  
  853. <URL:
  854. http://purl.net/stefan_ram/pub/java_referenzvariablen_als_argument_de>
  855.  
  856.  
  857. 3.1.4. Warum gibt es in Java keine Destruktoren wie in C++?
  858.        Autor: Markus Reitz
  859. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  860. In Java hat der Programmierer unter normalen UmstΣnden keinen direkten
  861. Einflu▀ darauf, wann Objekte aus dem Speicher entfernt werden. So ist
  862. es unter anderem nicht m÷glich, ein Objekt per Befehl aus dem Speicher
  863. zu l÷schen. Dies erledigt der sogenannte Garbage-Collector, der Objekte
  864. aus dem Speicher entfernt, auf die keine Referenz mehr verweist.
  865. Dadurch wird verhindert, da▀ der Programmierer mehr oder minder
  866. mutwillig Speicherfehler erzeugen kann, die das Programm zum Absturz
  867. bringen k÷nnten. Wann die Entfernung aus dem Speicher erfolgt, liegt im
  868. Ermessen des Computers. Es gibt also keinen definierten Zeitpunkt, wann
  869. ein Objekt nicht mehr existiert und deshalb ist es in den meisten FΣllen
  870. nicht sinnvoll, Operationen zu definieren, die beim L÷schen des
  871. Objektes ausgefⁿhrt werden. Man k÷nnte (ungⁿltige) Annahmen voraussetzen
  872. - zum Beispiel bei verketteten Listen, da▀ das Nachfolgerelement noch
  873. existiert, obwohl dies gar nicht der Fall ist - und damit Fehler
  874. verursachen. Destruktoren wie in C++ existieren deshalb nicht. Ist es
  875. aus irgendeinem dringenden Grund dennoch n÷tig, Operationen beim L÷schen
  876. des Objektes auszufⁿhren, so kann man eine Methode finalize definieren,
  877. die bei der Speicherbereinigung abgearbeitet wird. Wobei nicht garantiert
  878. wird die finalize methode ⁿberhaupt von der JVM abgearbeitet wird.
  879.  
  880.  
  881. 3.1.5. Warum funktioniert die equals Methode nicht?
  882.        Autor: Markus Reitz
  883.        Autor: Martin Erren
  884. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  885. Problem 1:
  886.  
  887. Man hat eine eigene Klasse entworfen und m÷chte nun testen, ob zwei
  888. Objekte gleich sind. Fein, denkt man sich, dafⁿr bietet die Klasse
  889. Object ja die Methode equals(Object obj). Doch das Programm mit
  890. Verwendung der equals(Object obj) Methode wird zwar korrekt ⁿbersetzt,
  891. der Vergleich funktioniert jedoch nicht so, wie er eigentlich sollte.
  892.  
  893. Per Default sagt equals(), dass es sich um die selbe Instanz einer
  894. Klasse handelt:
  895.  
  896. public class Object {
  897.     ...
  898.  
  899.     public boolean equals(Object other) {
  900.         return this == other;
  901.     }
  902.  
  903.     ...
  904. }
  905.  
  906. L÷sung 1:
  907.  
  908. Die Methode equals(Object obj) mu▀ fⁿr jede Klasse neu ⁿberschrieben
  909. werden. Schlie▀lich kann man nicht in allgemeiner Weise die Gleichheit
  910. zweier Objekte einer Klasse spezifizieren. Das ist insbesondere dann
  911. wichtig falls die Objekte in einer Set oder als Keys fⁿr eine Map
  912. verwendet werden. Dann muss allerdings auch die Methode hashCode()
  913. ⁿberschrieben werden.  Siehe dazu auch die nΣchste Frage in dieser FAQ!
  914.  
  915. Dazu sollte man sich auf alle FΣlle in der JavaDoc zu Object, speziell
  916. die Methoden hashCode() und equals(Object obj) ansehen:
  917.  
  918.     <URL:http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html>
  919.  
  920. Fⁿr Strings beispielsweise sind equals() und hashCode() bereits
  921. ⁿberschrieben. So dass String-Objekte als Keys verwandt werden k÷nnen.
  922.  
  923.  
  924. Problem 2:
  925.  
  926. public class Test {
  927.  
  928.     private int a;
  929.     private int b;
  930.  
  931.     public Test (int a , int b) {
  932.         this.a = a;
  933.         this.b = b;
  934.     }
  935.  
  936.     public boolean equals(Test other) {
  937.         return (this.a == other.a) && (this.b == other.b);
  938.     }
  939. }
  940.  
  941. Verwendet man nun Objekte dieser Klasse in Containerklassen und hier
  942. insbesondere Methoden, die auf die Methode equals des Objekts
  943. zurⁿckgreifen, so funktioniert dies nicht. Der Grund liegt in der
  944. falschen Signatur der Methode equals. Der Parameter mu▀ vom Typ Object
  945. sein und nicht vom Typ der Klasse, zu dem die Methode geh÷rt. Ansonsten
  946. existieren fⁿr die Klasse Test zwei Versionen der equals Methode: Eine,
  947. die von der Klasse Object geerbt wurde und die als Parametertyp auch
  948. Object besitzt und als zweite die oben definierte. Containerklassen
  949. verwenden aber die erste und da diese nicht verΣndert wurde, wird nicht
  950. das gewⁿnschte Ergebnis erzielt.
  951.  
  952. L÷sung 2:
  953.  
  954. public class Test {
  955.  
  956.     private int a;
  957.     private int b;
  958.  
  959.     public void Test (int a , int b) {
  960.         this.a = a;
  961.         this.b = b;
  962.     }
  963.  
  964.     //Die hash-Funktion ist aus dem Buch "Effective Java" von
  965.     //Joshua Bloch.
  966.     public int hashCode() {
  967.         int result = 17;
  968.         result = 37*result + this.a;
  969.         result = 37*result + this.b;
  970.         return result;
  971.     }
  972.  
  973.     public boolean equals(Object obj) {
  974.         //Fⁿr eine bessere Performance.
  975.         if (this == obj) {
  976.             return true;
  977.         }
  978.         //Wenn (obj == null) dann gibt instanceof false zurⁿck
  979.         //Siehe JLS 15.20.2
  980.         if (!(obj instanceof Test)) {
  981.             return false;
  982.         }
  983.         Test other = (Test)obj;
  984.         return (this.a == other.a) && (this.b == other.b);
  985.     }
  986. }
  987.  
  988.  
  989. 3.1.6. Wenn ich eigene Objekte mit einer Hashtable/HashMap verwalte,
  990.        kommt es zu sonderbaren Effekten. Wieso?
  991.        Autor: Ingo R. Homann, Gerhard Bloch
  992. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  993. Damit eigene Objekte als Schluessel in einer Hashtable/HashMap
  994. funktionieren, muessen zwei Bedingungen erfuellt sein:
  995.  
  996. 1. Wenn man die equals-Methode einer Klasse ⁿberschreibt, sollte man
  997.    beachten, dass man auch die hashCode-Methode ⁿberschreiben mu▀!
  998. 2. Nichts, was equals-Vergleiche beeinflusst, darf geaendert werden,
  999.    waehrend das Objekt in einer Hashtable/HashMap ist! Insbesondere darf
  1000.    sich der Hashcode nicht aendern.
  1001.  
  1002. Man muss sicherstellen, dass Objekte, die laut der equals-Methode gleich
  1003. sind, auch einen identischen Hashcode haben mⁿssen. Der Umkehr-Schluss,
  1004. dass ungleiche Objekte (bei denen equals false liefert) zwangslΣufig
  1005. auch unterschiedliche Hashcodes haben mⁿ▀en, gilt nicht. Trotzdem sollte
  1006. man als Programmierer versuchen, m÷glichst darauf hinzuarbeiten (und
  1007. keineswegs z.B. fⁿr alle Objekte einen gleichen, konstanten Hashcode
  1008. liefern!), damit die Implementierungen von Hashtable und HashMap
  1009. effizient arbeiten k÷nnen.
  1010.  
  1011. Als Folge dieser Forderung sollten zur Berechnung des Hashcode genau die
  1012. Attributwerte einbezogen werden, die auch zur equals-Bestimmung
  1013. verwendet werden, insbesondere aber keine anderen Werte!
  1014.  
  1015. Die Forderung kann auch so formuliert werden:
  1016.         a.equals(b) => (a.hashCode() == b.hashCode())
  1017. oder    (a.hashCode() != b.hashCode()) => !a.equals(b)
  1018.  
  1019.  
  1020. Eine Hashtable funktioniert vereinfacht folgendermassen:
  1021. Die Schluessel-Wert-Paare werden beim Einfuegen in Buckets ("Eimer")
  1022. verteilt. Dabei entscheidet der Hashcode des Schluessels, in welchen
  1023. Bucket er kommt.
  1024. Beim Suchen wird anhand des Hashcodes des Suchschluessels der Bucket
  1025. ermittelt, in dem das gesuchte Objekt liegen muss. So k÷nnen (au▀er
  1026. in ungⁿnstigen FΣllen) fast alle Schluessel der Tabelle ausgeschlossen
  1027. werden, der Suchschluessel muss nur noch innerhalb des Buckets gesucht
  1028. werden; falls er (genauer: ein Schluessel, dessen equals-Vergleich mit
  1029. dem Suchschluessel true ergibt) dort gefunden wird , wird der Wert
  1030. zurueckgegeben.
  1031. Dies funktioniert deshalb, weil aufgrund der obigen Forderung nur
  1032. diejenigen Objekte uebereinstimmen koennen, die auch im Hashcode
  1033. uebereinstimmen (equals => gleicher Hashcode).
  1034.  
  1035. Ein Problem ergibt sich, wenn nach dem Einfuegen ein Schluessel
  1036. geaendert wird. Da sich dadurch auch dessen Hashcode (mit ziemlicher
  1037. Sicherheit) aendert, liegt er nun im falschen Bucket. Die Hashtable
  1038. bekommt von der Aenderung ja nichts mit!
  1039. Deshalb ist zu beachten, dass sich Schluessel nicht aendern, solange sie
  1040. in einer Hashtable verwendet werden. Sichergestellt werden kann dies nur
  1041. durch immutalbe Objekte (siehe 3.10.7).
  1042.  
  1043. Beispiel fuer das richtige Ueberschreiben von hashCode:
  1044.  
  1045. public class Name {
  1046.     private static int zaehler= 0;
  1047.  
  1048.     private String     vorname
  1049.     private String     nachname;
  1050.     private final int  id = zaehler++;
  1051.  
  1052.     public Name(String vorname, String nachname) {
  1053.         this.vorname = vorname;
  1054.         this.nachname = nachname;
  1055.     }
  1056.  
  1057.     public boolean equals(Object o) {
  1058.         // die id ist nur fuer interne Zwecke und hat keinen Einfluss
  1059.         // auf Gleichheit
  1060.         if(o instanceof Name) {
  1061.             Name n = (Name)o;
  1062.             return vorname.equals(n.vorname) &&
  1063.                    nachname.equals(n.nachname);
  1064.         } else {
  1065.             return false;
  1066.         }
  1067.     }
  1068.  
  1069.     public int hashCode() {
  1070.         // Es werden genau die Werte einbezogen, die auch in der
  1071.         // equals-Methode verwendet werden
  1072.         int result = 17;
  1073.         result = 37*result + vorname.hashCode();
  1074.         result = 37*result + nachname.hashCode();
  1075.         return result;
  1076.     }
  1077. }
  1078.  
  1079.  
  1080. 3.1.7. Was bedeutet das Schlⁿsselwort final?
  1081.        Orginalautor: Markus Reitz
  1082.        Autor: Paul Ebermann
  1083. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1084. Klassen oder Methoden, die das Schlⁿsselwort final tragen, k÷nnen nicht
  1085. mehr ⁿberschrieben werden, wenn von dieser Klasse abgeleitet wird. Die
  1086. Verwendung dieses Schlⁿsselwortes bietet sich aus zwei Grⁿnden an:
  1087.  
  1088.   - Realisierung von Sicherheitsma▀nahmen
  1089.   - Codeoptimierung
  1090.  
  1091. Sicherheitsma▀nahmen werden realisiert, weil es nicht m÷glich ist, die
  1092. Bedeutung der Methode in abgeleiteten Klassen zu verΣndern und damit
  1093. bestehende Konzepte zu durchbrechen. Codeoptimierung deshalb, weil der
  1094. Compiler nun davon ausgehen kann, da▀ sich an den Methoden nichts mehr
  1095. Σndern wird und deshalb elegantere Codeoptimierungen m÷glich sind. In
  1096. Anbetracht der Tatsache, da▀ final-Methoden nicht mehr verΣndert werden
  1097. k÷nnen, mu▀ man sich beim Programmentwurf sehr sicher sein, da▀ das
  1098. Feature des ▄berschreibens definitiv nicht fⁿr diese Methode ben÷tigt
  1099. wird, ansonsten kann es bei Verbesserungen des Codes zu Problemen
  1100. kommen.
  1101.  
  1102. Wenn Variablen mit dem Schlⁿsselwort final deklariert werden, hat das
  1103. zur Folge, dass ihr Wert nur einmal zugewiesen (initialisiert) und dann
  1104. nicht mehr verΣndert werden kann. Wenn der Compiler das nicht nachweisen
  1105. kann, gibt es einen Fehler.
  1106.  
  1107. * Bei Exemplarvariablen kann die Zuweisung direkt in der Deklaration, in
  1108. einem Initialisierungsblock oder in (dann allen) Konstruktoren erfolgen.
  1109. Bei Klassenvariablen kann die Zuweisung direkt in der Deklaration oder
  1110. in einem Klassen-Initialisierungsblock erfolgen.
  1111.  
  1112. * Bei lokalen Variablen muss die Zuweisung in der Deklaration oder
  1113. irgendwo spΣter im Code, jedenfalls vor dem ersten Lese-Zugriff erfolgen.
  1114.  
  1115. * Bei Methoden- oder Konstruktor-Parametern mit final kann keine
  1116. Zuweisung erfolgen.
  1117.  
  1118.  
  1119. 3.1.8. Warum wird der dynamische Parametertyp bei ⁿberladenen
  1120.        Funktionen nicht beachtet?
  1121.        Autor: Uwe Gⁿnther, Erwin Hoffmann, Markus Reitz
  1122. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1123. Dies ist ein korrektes Verhalten gemΣ▀ der Java-Sprachspezifikation!
  1124.  
  1125. Die Entscheidung, welche ⁿberladene Methode bei der ▄bergabe eines
  1126. bestimmten Parameters auszuwΣhlen ist, wird nicht anhand des Typs des
  1127. an die Methode ⁿbergebenen Objekts getroffen, sondern anhand des Typs
  1128. der Referenz, die auf das ⁿbergebene Objekt verweist.
  1129. Diese Entscheidung wird vom Compiler getroffen. Hier muss also zur
  1130. Compilezeit entschieden werden, welche Methode aufgerufen werden soll.
  1131. Der Compiler kann sich nur auf den Referenztyp beziehen, weil der
  1132. Objekttyp nur dynamisch zur Laufzeit eines Programms festgestellt werden
  1133. kann.
  1134.  
  1135. Das Ganze demonstriert ein Beispielprogramm:
  1136.  
  1137. public class BasisKlasse {}
  1138.  
  1139. public class AbgeleiteteKlasse extends BasisKlasse {}
  1140.  
  1141. public class Test {
  1142.     public static void methode(BasisKlasse eineKlasse) {
  1143.         System.out.println("Methode mit BasisKlasse!");
  1144.     }
  1145.  
  1146.     public static void methode(AbgeleiteteKlasse eineKlasse) {
  1147.         System.out.println("Methode mit AbgeleiteteKlasse!");
  1148.     }
  1149.  
  1150.     public static void testMethode(BasisKlasse a) {
  1151.         if (a instanceof AbgeleiteteKlasse) {
  1152.             System.out.print("Abgeleitet: ");
  1153.         } else {
  1154.             System.out.print("Basis: ");
  1155.         }
  1156.  
  1157.         //Welche Methode wird jetzt gerufen?
  1158.         methode(a);
  1159.     }
  1160.  
  1161.     public static void main (String[] params) {
  1162.         BasisKlasse a = new BasisKlasse();
  1163.         AbgeleiteteKlasse b = new AbgeleiteteKlasse();
  1164.         testMethode(a);
  1165.         testMethode(b);
  1166.     }
  1167. }
  1168.  
  1169. Das Programm erzeugt folgende Ausgabe:
  1170.  
  1171.     Basis: Methode mit BasisKlasse!
  1172.     Abgeleitet: Methode mit BasisKlasse!
  1173.  
  1174.  
  1175. 3.1.9. Was bedeutet super()?
  1176.        Autor: Markus Reitz
  1177. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1178. Werden Ableitungen von Klassen gebildet und dabei Funktionen redefiniert
  1179. (ⁿberschrieben), so ist es in vielen FΣllen n÷tig, auf die
  1180. FunktionalitΣt der Basisklasse zurⁿckzugreifen. Mit super.methode()
  1181. teilt man mit, da▀ man die Methode der Basisklasse und nicht die
  1182. Methode der aktuellen Klasse benutzen will. Innerhalb eines
  1183. Konstruktors ist es m÷glich mit super() den Konstruktor der Basisklasse
  1184. aufzurufen. Findet im Konstruktor kein expliziter Aufruf mit super()
  1185. statt, so wird automatisch der parameterlose Konstruktor
  1186. (Standardkonstruktor) der Basisklasse aufgerufen.
  1187.  
  1188.  
  1189. 3.1.10. Was sind anonyme Arrays?
  1190.         Autor: Markus Reitz
  1191. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1192. Ab Java 1.1 ist folgender Code gⁿltig:
  1193.  
  1194. int i[];
  1195. i = new int[] {1, 2, 3};
  1196.  
  1197. Es ist jetzt also m÷glich, Arrays auch au▀erhalb der Definition mit den
  1198. gewⁿnschten Werten zu initialisieren, indem man mit {...} einfach die
  1199. Werte angibt, die das neue Array tragen soll.
  1200.  
  1201.  
  1202. 3.1.11. Gibt es in Java einen PrΣ-Prozessor wie in C++?
  1203.         Autor: Markus Reitz
  1204. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1205. Nein. In C++ existiert der sogenannte PrΣ-Prozessor, der es mit
  1206. bestimmten Kommandos erlaubt, Teile des Codes zu ⁿbersetzen und andere
  1207. Teile bei der ▄bersetzung zu ⁿberspringen. Unter UmstΣnden wΣre es
  1208. hilfreich, wenn auch Java eine solche M÷glichkeit der
  1209. Compilationssteuerung zulassen wⁿrde, doch einen PrΣ-Prozessor gibt es
  1210. hier nicht. Man kann dies aber, zumindest ansatzweise, mit if-Statements
  1211. nachbilden. Dazu definiert man eine boolesche Variable DEBUG und in
  1212. AbhΣngigkeit von dieser Variablen sollen bestimmte Codeteile ausgefⁿhrt
  1213. werden, andere dagegen nicht.
  1214.  
  1215. public class Test {
  1216.     final static boolean DEBUG = true;
  1217.  
  1218.     public static void main (String[] params) {
  1219.         int i = 12;
  1220.         if (DEBUG) {
  1221.             System.out.println("Der Wert von i ist " + i);
  1222.         }
  1223.     }
  1224. }
  1225.  
  1226. Verwendet man nun noch Optimierer, die unbenutzten Code aus den
  1227. Klassendateien entfernen, so hat man im Prinzip ein Σhnliches Verhalten
  1228. wie beim PrΣ-Prozessor von C++. In diesem Zusammenhang ist es noch
  1229. erwΣhnenswert, da▀ das Verfahren nur bei der if-Abfrage m÷glich ist,
  1230. denn das Java-System prⁿft normalerweise darauf, ob Codezeilen erreicht
  1231. werden k÷nnen oder nicht und gibt gegebenenfalls Fehlermeldungen aus.
  1232. Das if-Statement ist jedoch wie oben beschrieben erweitert worden, um
  1233. das gewⁿnschte Verhalten simulieren zu k÷nnen. Dahingegen wird folgender
  1234. Code mit einer Fehlermeldung quittiert:
  1235.  
  1236. public class Test {
  1237.     final static boolean DEBUG = true;
  1238.  
  1239.     public static void main (String[] params) {
  1240.         int i = 12;
  1241.         while (DEBUG) {
  1242.             System.out.println("Der Wert von i ist " + i);
  1243.         }
  1244.     }
  1245. }
  1246.  
  1247. Denn es wⁿrde sich je nach Zustand von DEBUG eine Endlosschleife
  1248. ergeben.
  1249.  
  1250.  
  1251. 3.1.12. Existiert der const Modifizierer von C++ auch in Java?
  1252.         Autor: Markus Reitz
  1253. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1254. C++ kennt das Schlⁿsselwort const, das es erlaubt, konstante Objekte zu
  1255. definieren, deren Wert man nicht Σndern kann. Auf ein solches Objekt kann
  1256. man nur Methoden anwenden, die ebenfalls als const definiert sind, die
  1257. also die Daten des Objektes nicht Σndern k÷nnen.
  1258.  
  1259. Ab Java 1.1 k÷nnen Argumente mit dem Modifizierer final als konstant
  1260. definiert werden. Bei einer Objektreferenz bedeutet dies allerdings nur,
  1261. da▀ die Referenz konstant bleibt, nicht aber das Objekt, auf das die
  1262. Referenz verweist.
  1263.  
  1264. Da Java den Modifizierer const nicht kennt, ist es aber trotzdem recht
  1265. einfach m÷glich, diesen nachzubilden. Alles, was man dazu braucht, ist
  1266. ein Interface, das die konstanten Methoden enthΣlt, die das Objekt nicht
  1267. Σndern k÷nnen. Will man nun ein konstantes Objekt zurⁿckgeben oder
  1268. erzeugen, dann gibt man einfach eine Referenz vom Typ des Interfaces
  1269. zurⁿck und schon hat man das Gewⁿnschte erzielt.
  1270.  
  1271. Folgendes Beispiel soll das Ganze etwas verdeutlichen:
  1272.  
  1273. interface KonstanterTyp {
  1274.     public int get();
  1275. }
  1276.  
  1277. public class NichtKonstanterTyp implements KonstanterTyp {
  1278.  
  1279.     int i;
  1280.  
  1281.     public void set(int i) {
  1282.         this.i = i;
  1283.     }
  1284.  
  1285.     public int get() {
  1286.         return this.i;
  1287.     }
  1288. }
  1289.  
  1290. Ein konstantes Object wird dann durch
  1291.  
  1292.     KonstanterTyp A = new NichtKonstanterTyp();
  1293.  
  1294. erzeugt.
  1295.  
  1296. Anmerkung: Im Prinzip wird hier durch das Interface eine Art Untermenge
  1297. der Klasse  NichtKonstanterTyp  definiert. Bei C++ lΣuft dieser Proze▀
  1298. im Prinzip auch so ab, nur wird hier vom Compiler automatisch diese
  1299. Untermenge durch den Modifizierer const erzeugt und der Programmierer
  1300. mu▀ sich hierum nicht kⁿmmern. In Java mu▀ man diesen Proze▀ selbst
  1301. durchfⁿhren.
  1302.  
  1303.  
  1304. 3.1.13. Wie kann man Referenzen von ▄bergabeparametern Σndern?
  1305.         Autor: Markus Reitz
  1306. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1307. Von Sprachen wie C++ oder Pascal kennt man die M÷glichkeit, Referenzen,
  1308. die an die Methode ⁿbergeben werden, innerhalb der Methode zu Σndern, an
  1309. die sie ⁿbergeben wurden, wodurch nach dem Aufruf der Methode die
  1310. Referenzen auf andere Objekte verweisen.
  1311.  
  1312. In Java gibt es zwei M÷glichkeiten, diesen Effekt zu erreichen:
  1313.  
  1314.   - Einfⁿhren einer weiteren Ebene mit Wrapper-Klassen, die spezielle
  1315.     Referenzen zur Verfⁿgung stellen.
  1316.   - Verwendung von eindimensionalen, einelementigen Arrays.
  1317.  
  1318. Der erste Punkt dⁿrfte klar sein, jedoch steht der Aufwand erst dann in
  1319. einem vernⁿnftigen VerhΣltnis zum Ergebnis, wenn diese Art der
  1320. Parametermodifikation ÷fter innerhalb des Programms vorkommt, denn
  1321. ansonsten lohnt sich das Design einer speziellen Klasse nicht unbedingt.
  1322. Den zweiten Weg verdeutlicht das folgende Programm:
  1323.  
  1324. public class Test {
  1325.     public void parameterModifikation(Object[] paramter) {
  1326.         parameter[0] = "Neue Referenz";
  1327.     }
  1328.     public static void main (String[] args) {
  1329.         Objcet parameter[] = new Object[1];
  1330.         parameter[0] = "Zu modifizierender Parameter."
  1331.         Test test = new Test();
  1332.         System.out.println(parameter[0]);
  1333.         test.parameterModifikation(parameter);
  1334.         System.out.println(parameter[0]);
  1335.     }
  1336.  
  1337. }
  1338.  
  1339. Das Beispielprogramm liefert folgende Ausgabe:
  1340.  
  1341.     Zu modifizierender Parameter
  1342.     Neue Referenz
  1343.  
  1344.  
  1345. 3.1.14. Wie erzeuge ich eine  tiefe  Kopie eines Objektes mit m÷glichst
  1346.         wenig Aufwand?
  1347.         Autor: Markus Reitz
  1348.         Autor: Ingo R. Homann
  1349. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1350. Weist man einer Objektvariablen eine andere zu, so wird nur die Referenz
  1351. kopiert und beide Objektvariablen k÷nnen das Objekt modifizieren und
  1352. diese Modifikation auch sehen. Dies ist das Standardverhalten von Java.
  1353. Durch clone() wird z.B. eine flache Kopie von dem Vector angelegt,
  1354. d.h. z.B. das Hinzufⁿgen eines neuen Elements in die Kopie des Vektors
  1355. ist im Original-Vector nicht sichtbar. Die enthaltenen Objekte jedoch
  1356. werden *nicht* mitkopiert, d.h. ─nderungen an den enthaltenen Objekten
  1357. sind in beiden Vectoren sichtbar. Wenn wirklich alles - also auch die
  1358. enthaltenen Objekte und die rekursiv darin enthaltenen Objekte - kopiert
  1359. werden soll, dann braucht man eine sog. tiefe Kopie.
  1360.  
  1361. Ein sehr eleganter Weg, eine tiefe Kopie eines Objektes zu erzeugen,
  1362. verwendet den Serialisierungs-Mechanismus. Objekte, die man mit diesem
  1363. Verfahren kopieren m÷chte, mⁿssen also das Interface Serializable
  1364. implementieren.
  1365.  
  1366. import java.io.ByteArrayOutputStream;
  1367. import java.io.ByteArrayInputStream;
  1368. import java.io.ObjectOutputStream;
  1369. import java.io.ObjectInputStream;
  1370. import java.io.IOException;
  1371.  
  1372. public class TiefeKopie {
  1373.     public static Object kopiere(Object einObjekt)
  1374.             throws IOException {
  1375.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  1376.         ObjectOutputStream oos = new ObjectOutputStream(baos);
  1377.  
  1378.         oos.write(einObjekt);
  1379.  
  1380.         ByteArrayInputStream bais =
  1381.                 new ByteArrayInputStream(baos.toByteArray());
  1382.         ObjectInputStream ois = new ObjectInputStream(bais);
  1383.  
  1384.         return ois.readObject();
  1385.     }
  1386. }
  1387.  
  1388. Zuerst werden zwei Ausgabestr÷me angelegt: Ein Byte-Strom und ein
  1389. Object-Strom. Der Byte-Strom wird hinter den Object-Strom geschaltet und
  1390. das zu kopierende Objekt wird auf dem Object-Strom ausgegeben und durch
  1391. die Verknⁿpfung der beiden Str÷me schlie▀lich in den Byte-Strom
  1392. geschrieben. Dieser Byte-Strom wird dann mit einem zweiten Strom wieder
  1393. eingelesen und mit einem weiteren Object-Strom wird aus den einzelnen
  1394. Bytes wieder ein Objekt rekonstruiert. Die Ausgabe des Object-Stroms ist
  1395. dann das kopierte Objekt.
  1396.  
  1397. Die Anwendung der Klasse zeigt folgendes Codefragment:
  1398.  
  1399. public class Test {
  1400.     public static void main(String[] args) {
  1401.         int einArray[] = {56, 42, 67, 90, 12, 45};
  1402.         int tiefeKopieVonEinArray = (int[]) TiefeKopie.kopiere(einArray);
  1403.     }
  1404. }
  1405.  
  1406. Ein Array ist in Java nichts weiteres als ein Objekt und implementiert
  1407. auch das Serializeable-Interface, weshalb das obige Kopierverfahren
  1408. problemlos greifen kann.
  1409.  
  1410. Anmerkung: Bei komplexen Objekten, die viele Referenzen auf andere
  1411. Objekte besitzen schlΣgt das Verfahren meist fehl. Der
  1412. Serialisierungsmechanismus verwendet Rekursion, um alle referenzierten
  1413. Objekte zu speichern. Wird auf Objekte referenziert, die wieder auf
  1414. Objekte referenzieren usw. kann es geschehen, da▀ der Stack-Speicher
  1415. fⁿr die Rekursion ⁿberlΣuft. Diese elegante Methode der tiefen Kopie
  1416. kann also nur bei  einfachen  Objekten angewendet werden. In Sachen
  1417. Performance liegt diese L÷sung jedoch um einiges hinter der klassischen
  1418. L÷sung alle Elemente einzeln zu kopieren. Dessen sollte man sich klar
  1419. sein, wenn man diese L÷sung einsetzt.
  1420.  
  1421.  
  1422. 3.1.15. Wie kann ich in Java eine dem Programmierer unbekannt Anzahl
  1423.         gleichartiger Objekte erzeugen und ihnen passende Namen zuweisen,
  1424.         also label1, label2 usw.?
  1425.         Autor: Michael Paap, Christian Kaufhold
  1426. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1427. Das ist in dieser Form nicht sinnvoll. Die bessere L÷sung
  1428. besteht in der Verwendung eines Arrays. In Java kann die
  1429. Gr÷▀e eines Arrays bei seiner Erzeugung zur Laufzeit
  1430. (einmalig!) festgelegt werden. Ein Zugriff auf die einzelnen
  1431. Objekte erfolgt dann ⁿber den Arrayindex:
  1432.  
  1433.  
  1434. // Deklaration
  1435. Label[] myLabels;
  1436.  
  1437. ...
  1438.  
  1439. // Erzeugung und Initalisierung zur Laufzeit
  1440. int anzahl = 10;
  1441. myLabels = new Label[anzahl];
  1442.  
  1443. for (int i = 0; i < myLabels.length; i++) {
  1444.     myLabels[i] = new Label("Label Nr. " + i);
  1445. }
  1446.  
  1447. // Verwendung
  1448. myLabel[3].setBackground(Color.red);
  1449.  
  1450.  
  1451. 3.1.16. Wie kann ich den Typ enum aus C++ in Java umsetzen?
  1452.         Autor: Markus Reitz, Uwe Gⁿnther, Ulf JΣhrig
  1453. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1454.  
  1455. C++ bietet einen sogenannten Enumerationstyp. Eine Variable eines
  1456. solchen Typs kann nur definierte Werte annehmen, die mit symbolischen
  1457. Namen bezeichnet werden. Folgende Enumeration k÷nnte zum Beispiel fⁿr
  1458. eine Ampel verwendet werden:
  1459.  
  1460.     enum Ampel {ROT, GELB, GRUEN};
  1461.  
  1462. Java bietet diesen Typ nicht, kann diesen aber recht einfach mit einem
  1463. Interface nachbilden:
  1464.  
  1465. interface Ampel {
  1466.     public static final int ROT = 1;
  1467.     public static final int GELB = 2;
  1468.     public static final int GRUEN = 3;
  1469. }
  1470.  
  1471. Ein C++ Compiler fⁿhrt automatisch die Zuordnung von Variablennamen zu
  1472. eindeutigen Zahlenwerten durch, in Java mu▀ der Programmierer diesen
  1473. Proze▀ erledigen. Die Verwendung differiert zwischen Java und C++:
  1474.  
  1475.     Ampel eineVariable = ROT; // Das ist C++
  1476.     int eineVariable = Ampel.ROT; // Das ist Java
  1477.  
  1478. Man erkennt einen gro▀en Nachteil der Java-Version: Da es sich um eine
  1479. int-Variable handelt, ist es prinzipiell m÷glich, jeden Wert an diese
  1480. Variable zuzuweisen, eben nicht nur Werte aus dem Wertebereich rot, gruen
  1481. und gelb. Im Gegensatz dazu lΣ▀t ein C++-Compiler nur Zuweisungen von
  1482. Symbolen aus dem Enumerationstyp zu. Insofern ist die Nachbildung in Java
  1483. weniger sicher als das C++-Pendant und sollte daher mit Vorsicht
  1484. angewendet werden. Sprich sie ist nicht Typsicher!
  1485.  
  1486. Wie schon oben angesprochen, bietet diese direkte Implementierung den
  1487. Nachteil, da▀ sie nicht typsicher ist. Doch es ist recht einfach m÷glich,
  1488. mit Java eine typsichere Implementierung zu erhalten:
  1489.  
  1490. public final class Ampel {
  1491.  
  1492.     private String name;
  1493.     public final int ord;
  1494.     private static int obereGrenze = 0;
  1495.  
  1496.     private Ampel(String name) {
  1497.         this.name = name;
  1498.         this.ord = obereGrenze++;
  1499.     }
  1500.  
  1501.     public String toString() {
  1502.         return this.name;
  1503.     }
  1504.  
  1505.     public static int groesse() {
  1506.         return this.obereGrenze;
  1507.     }
  1508.  
  1509.     public static final Ampel ROT = new Ampel("Rot");
  1510.     public static final Ampel GELB = new Ampel("Gelb");
  1511.     public static final Anpel GRUEN = new Ampel("Gruen");
  1512. }
  1513.  
  1514. Besonders interessant ist hier die Kombination von automatischer
  1515. Zuweisung eines eindeutigen Zahlenwertes mit den Symbolwerten eines
  1516. Strings.
  1517.  
  1518. Auf den ersten Blick sieht die Klassendefinition ziemlich kompliziert und
  1519. unverstΣndlich aus, das Prinzip ist jedoch nicht schwer zu verstehen:
  1520.  
  1521.   - Zuersteinmal ist die Klasse als final deklariert, wodurch verhindert
  1522.     wird, da▀ von dieser Klasse Ableitungen gebildet werden k÷nnen. Der
  1523.     AufzΣhlungstyp kann also - weder absichtlich noch unabsichtlich -
  1524.     durch Vererbung verΣndert werden.
  1525.  
  1526.   - Der Konstruktor der Klasse ist private, dadurch kann er nur von
  1527.     der Klasse selbst aufgerufen werden. Damit sind die einzigen
  1528.     Instanzen, die von Ampel erzeugt werden k÷nnen, die, die den
  1529.     public-Variablen der Klassen zugewiesen sind.
  1530.  
  1531.   - Einer Referenz vom Typ Ampel k÷nnen durch diese Ma▀nahmen nur die
  1532.     Werte {ROT, GELB, GRUEN} zugewiesen werden, andere Instanzen vom
  1533.     Typ Ampel sind ausgeschlossen, weil sie niemals existieren werden.
  1534.  
  1535.   - Die ▄berlagerung von toString hat den Zweck, einem das Leben beim
  1536.     Debuggen einfacher zu machen.
  1537.  
  1538. Will man nun diesen Typ von Enumeration benutzen, so sieht das in etwa
  1539. wie folgt aus:
  1540.  
  1541. public class Test {
  1542.     public static void main(String[] args){
  1543.         Ampel meineAmpel = Ampel.ROT;
  1544.  
  1545.         if (meineAmpel == Ampel.ROT) {
  1546.             System.out.println("Ampel ist " + meineAmpel + ". ");
  1547.             System.out.println("Anhalten!");
  1548.         }
  1549.         if (meineAmpel == Ampel.GELB) {
  1550.             System.out.println("Ampel ist " + meineAmpel + ". ");
  1551.             System.out.println("Motor starten -oder- Anhalten!");
  1552.         }
  1553.         if (meineAmpel == Ampel.GRUEN) {
  1554.             System.out.println("Ampel ist " + meineAmpel + ". ");
  1555.             System.out.println("Gib Gas!");
  1556.         }
  1557.     }
  1558. }
  1559.  
  1560. Dieser Typ der Enumeration verwendet also Referenzen und nicht, wie
  1561. Version 1, int-Werte, die nicht typsicher sind. Durch die
  1562. Typprⁿfungsmechanismen von Java wird diese Art von Enumeration
  1563. vollkommen typsicher und steht dem enum Konstrukt von C++ nun in nichts
  1564. mehr nach.
  1565.  
  1566. Wer mehr ⁿber dieses Pattern erfahren m÷chte sei dem sei folgender Link
  1567. empfohlen:
  1568.  
  1569. <URL:http://www.javaworld.com/javaworld/jw-07-1997/jw-07-enumerated.html>
  1570.  
  1571.  
  1572. 3.1.17. Kann man Mehrfachvererbung mit Java simulieren?
  1573.         Autor: Markus Reitz
  1574. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1575. Java kennt im Gegensatz zu C++ nicht das Feature der Mehrfachvererbung,
  1576. eine Klasse kann nur genau einen Vorfahren haben, im Gegensatz zu
  1577. beliebig vielen bei Mehrfachvererbung.
  1578.  
  1579. HΣufig liest man, da▀ man die Mehrfachvererbung mit Hilfe von Interfaces
  1580. nachbilden kann, indem man die Methodenschnittstelle der einzelnen
  1581. Klassen als Interfaces definiert und diese Interfaces alle gleichzeitig
  1582. von der fraglichen Klasse implementieren lΣ▀t, denn dies ist in Java
  1583. m÷glich.
  1584.  
  1585. Mit Mehrfachvererbung hat dies aber nichts zu tun, wenn man den
  1586. eigentlichen Sinn und Zweck von Vererbung betrachtet. Vererbung ist
  1587. eines der m÷glichen Prinzipien, um die Codewiederverwertung zu
  1588. garantieren. Code, der in mehreren Klassen ben÷tigt wird, ist nur in der
  1589. Basisklasse aufgefⁿhrt und durch die Vererbung k÷nnen die  Erben  auch
  1590. diesen Code benutzen. Der Code steht also nur an einer Stelle. Bei der
  1591. oben beschriebenen  Nachbildung  wird in keiner Weise Code gespart, denn
  1592. die Methoden der Interfaces mⁿssen ja von der Klasse noch implementiert
  1593. werden.
  1594.  
  1595. In diesem Sinne kann man Mehrfachvererbung nicht in Java nachbilden.
  1596.  
  1597.  
  1598. 3.1.18. Wie realisiere ich eine variable Parameterliste?
  1599.         Autor: Markus Reitz
  1600. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1601. Es gibt AnwendungsfΣlle, in denen es Σu▀erst nⁿtzlich wΣre, einer
  1602. Methode eine variable Anzahl an Parametern ⁿbergeben zu k÷nnen. Ein
  1603. Anwendungsfall wΣre eine Klasse beliebig-dimensionaler Vektoren. Ein
  1604. Konstruktor dieser Klasse mⁿ▀te die Initialisierung eines Vektors mit
  1605. bestimmten Werten erlauben und da beliebig-dimensionale Vektoren von
  1606. dieser Klasse verarbeitet werden, mⁿ▀te der Konstruktor mit einer
  1607. variablen Parameteranzahl arbeiten k÷nnen. Mit einem Trick kann man eine
  1608. variable Parameterliste realisieren: Man ⁿbergibt der Methode ein Array
  1609. von Referenzen auf die Klasse Object. Da in Java alle Objekte von der
  1610. Klasse Object abstammen - sie ist quasi die Klasse aller Klassen - kann
  1611. das Array Referenzen auf beliebige Objekte aufnehmen. Innerhalb der
  1612. Methode kann dann mit dem length-Feld des Arrays die Anzahl der
  1613. ⁿbergebenen Parameter ermittelt werden. Mit dem instanceof-Operator von
  1614. Java kann dann der Typ des Objekts ermittelt werden, auf den die
  1615. Referenzen verweisen und an Hand dieser Informationen kann man dann
  1616. festlegen, was getan werden soll. Ein Programmfragment verdeutlicht das
  1617. bisher Gesagte:
  1618.  
  1619. public class Test {
  1620.     void methodeMitVariablerParameterListe(Object[] parameterList) {
  1621.         //LΣnge: parameterList.length ===> Anzahl der Parameter
  1622.         //Typ:   if (parameterList[i] instanceof <Type>)
  1623.     }
  1624. }
  1625.  
  1626. Ein Nachteil ist offensichtlich: Es kann nur genau eine Methode mit
  1627. variabler Parameterliste geben bzw. innerhalb dieser einen Methode mⁿssen
  1628. alle Variationen berⁿcksichtigt und implementiert werden, was nicht
  1629. unbedingt zur ▄bersichtlichkeit des Programms beitrΣgt.
  1630.  
  1631. Ein Aufruf der Methode gestaltet sich nun wie folgt:
  1632.  
  1633. Test obj = new Test();
  1634. obj.methodeMitVariablerParameterListe(new Object[] {
  1635.         paramObject1, paramObject2, ..., paramObjectn
  1636.     });
  1637.  
  1638. Will man elementare Datentypen wie double oder int an die Methode
  1639. ⁿbergeben, so mu▀ man die zugeh÷rigen Wrapper-Klassen verwenden, die
  1640. diese elementaren Datentypen in Klassen  einpacken.
  1641.  
  1642.  
  1643. 3.1.19. Wie realisiere ich eine Methodenauswahl nach den dynamischen
  1644.         Parametertypen?
  1645.         Autor: Markus Reitz
  1646. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1647. Java wΣhlt Methoden nach dem statischen Typ der ▄bergabeobjekte aus. Man
  1648. kann jedoch eine dynamische Auswahl simulieren, indem man das oben
  1649. angesprochene Prinzip der variablen Parameter hierauf ⁿbertrΣgt. Man
  1650. prⁿft die ⁿbergebenen Referenzen mit dem instanceof-Operator, der den
  1651. dynamischen Typ des Parameters liefert. Anhand dieser Informationen kann
  1652. man dann ein  dynamisches  Verhalten der Methodenaufrufe realisieren.
  1653. Auch hier gilt, wie auch schon bei der variablen Parameterliste, da▀ eine
  1654. einzige Methode alle Aufrufm÷glichkeiten abdecken mu▀.
  1655.  
  1656.  
  1657. 3.1.20. Sind Methoden in Java immer virtuell?
  1658.         Autor: Markus Reitz
  1659. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1660. In Java sind alle Methoden virtuell, eine Unterscheidung zwischen
  1661. virtuellen und nicht-virtuellen Methoden wie zum Beispiel in C++, gibt es
  1662. in Java nicht. Ist es fⁿr die Funktionsweise eines Objektes wichtig, da▀
  1663. die vorhandenen Methoden nicht ⁿberschrieben werden k÷nnen - etwa um zu
  1664. verhindern, da▀ sich die FunktionalitΣt des Objekts dadurch grundlegend
  1665. Σndern lΣ▀t - so mu▀ man entsprechende Methoden mit dem Modifizierer
  1666. final deklarieren, der ein ▄berschreiben verhindert.
  1667.  
  1668.  
  1669. 3.1.21. Ich stosse ab und zu auf den Begriff "Wrapper-Klassen".
  1670.         K÷nnte mir jemand erklΣren was das ist?
  1671.         Autor: Stephan Menzel
  1672. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1673. Eine sehr gute Frage, auf die ich mal mit einem Zitat aus Go to Java 2
  1674. antworten moechte, denn sie wird zu selten gestellt:
  1675.  
  1676. Zitat (Goto Java 2):
  1677.  
  1678. Zu jedem primitiven Datentyp in Java gibt es eine korrespondierende
  1679. Wrapper-Klasse. Diese kapselt die primitive Variable in einer
  1680. objektorientierten Hⁿlle und stellt eine Reihe von Methoden zum Zugriff
  1681. auf die Variable zur Verfⁿgung. Zwar wird man bei der Programmierung
  1682. meist die primitiven Typen verwenden, doch gibt es einige Situationen,
  1683. in denen die Anwendung einer Wrapper-Klasse sinnvoll sein kann.
  1684.  
  1685. Diese Klassen, wie zum Beispiel "Integer" koennen einem das Leben
  1686. angenehmer gestalten, wenn man Dinge tun muss, die man mit einfachen
  1687. ints tun will, aber mangels vorhandener Methoden nicht kann, weil diese
  1688. Primitiven eben keine richtigen Objekte sind.
  1689.  
  1690. Zum Beispiel kann Integer (im Gegensatz zu int) Strings nach Zahlen
  1691. parsen, oder Integers als Binaercode ausgeben oder als Hex oder in
  1692. andere Zahlentypen umwandeln und vieles mehr. Vielleicht ist es fuer
  1693. Dich noch interessant zu erfahren, dass diese Wrapper Klassen in der
  1694. Praxis oftmals nicht instantiiert, sondern ihre Methoden statisch
  1695. aufgerufen werden.
  1696.  
  1697. Um zum Beispiel aus dem String "42" das betreffende int zu machen,
  1698. rufst Du:
  1699.  
  1700. String zweiundvierzig = new String ("42") ;
  1701. int answer = Integer.parseInt (zweiundvierzig) ;
  1702.  
  1703. Das brauchst Du zum Beispiel zum Auswerten von GUI-Zahlenfeldern.
  1704. Ich hoffe, ich konnte ein wenig Licht ins Dunkel bringen. Das
  1705. Verstaendnis von Wrapperklassen und deren Sinn halte ich naemlich fuer
  1706. essentiell, wenn man mit OOP beginnt.
  1707.  
  1708.  
  1709. 3.1.22. Warum ist private nicht privat?
  1710.         Autor: Markus Reitz
  1711. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1712.  
  1713. public class Person {
  1714.  
  1715.     private int kontostand;
  1716.  
  1717.     public Person(int kontostand) {
  1718.         this.kontostand = kontostand;
  1719.     }
  1720.  
  1721.     public void addGehalt(int gehalt) {
  1722.         this.kontostand += gehalt;
  1723.     }
  1724.  
  1725.     public void klauen(Person opfer) {
  1726.         this.kontostand += opfer.kontostand;
  1727.         opfer.kontostand = 0;
  1728.     }
  1729.  
  1730.     public void zeigeKontostand() {
  1731.         System.out.println("Kontostand: " + this.kontostand);
  1732.     }
  1733. }
  1734.  
  1735.  
  1736. public class Test {
  1737.     public static void main(String[] args) {
  1738.         //Der Dieb er÷ffnet ein Konto
  1739.         Person dieb = new Person(10);
  1740.  
  1741.         //Das Opfer er÷ffnet ein Konto
  1742.         Person opfer = new Person(50000);
  1743.  
  1744.         //Das Opfer bekommt Gehalt
  1745.         opfer.addGehalt(10000);
  1746.  
  1747.         //Der Dieb geht an die Arbeit
  1748.         dieb.klauen(opfer);
  1749.  
  1750.         //Das opfer ist nun pleite!!!
  1751.         opfer.zeigeKontostand();
  1752.  
  1753.         //Und der Dieb un 60000 Euro reicher.
  1754.         dieb.zeigeKontostand();
  1755.     }
  1756. }
  1757.  
  1758.  
  1759. Wenn man obiges Programm testet, so wird man feststellen, da▀ es m÷glich
  1760. ist, die private-Datenfelder eines Objektes zu manipulieren; diese Daten
  1761. sind also nicht privat im sonst ⁿblichen Sinne. Allerdings ist die
  1762. PrivatsphΣre nur fⁿr Objekte der gleichen Klasse aufgehoben, Objekte
  1763. anderer Klassen haben keinen Zugriff auf die private-Daten von Objekten
  1764. anderer Klassen. Damit ist obige M÷glichkeit nicht weiter tragisch, denn
  1765. der Entwickler der Klasse kann eine wie oben gezeigte M÷glichkeit
  1766. wirksam unterbinden. Wenn er dies nicht tut, so ist die Schuld bei ihm
  1767. zu suchen, denn nur der Entwickler allein ist fⁿr das Verhalten der
  1768. Klassen zustΣndig und nur der Entwickler mu▀ solche M÷glichkeiten durch
  1769. das Design ausschlie▀en. Die private-Deklaration ist damit als
  1770. Deklaration der PrivatsphΣre gegenⁿber Objekten anderer Klassen zu
  1771. sehen, zwischen Objekten der gleichen Klasse herrscht ein
  1772. freundschaftliches VerhΣltnis, sie dⁿrfen sich gegenseitig in die Daten
  1773. schauen.
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779. 3.2. [STRING] - Fragen die unmittelbar mit Strings zu tun haben.
  1780. ----------------------------------------------------------------
  1781.  
  1782. 3.2.1. Wie vergleiche ich zwei Strings in Java?
  1783.        Autor: Markus Reitz, Martin Erren
  1784. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1785. Problem:
  1786.  
  1787. Man versucht zwei Strings in der Form
  1788.  
  1789. if(stringEins == stringZwei) {
  1790.     System.out.println("stringEins und stringZwei sind gleich.");
  1791. }
  1792.  
  1793. zu vergleichen und erhΣlt alles andere als ein richtiges Ergebnis.
  1794.  
  1795. Der Grund ist der, da▀ mit dem "=="-Operator nur die beiden Referenzen
  1796. miteinander verglichen werden, nicht jedoch die Objekte. Man erhΣlt
  1797. deshalb wom÷glich auch bei zwei gleichen Strings das Ergebnis, da▀ sie
  1798. verschieden sind. Fⁿr den inhaltlichen Vergleich, nicht nur von Strings,
  1799. sondern allgemein von Objekten, wird in Java die Methode
  1800. equals(Object obj) verwendet, die nicht immer nur Referenzen, sondern
  1801. je nach Klasse auch die Inhalte (sprich ihre Daten) vergleicht. Obige
  1802. Abfrage mⁿ▀te also
  1803.  
  1804. if(stringEins.equals(stringZwei)) {
  1805.     System.out.println("stringEins und stringZwei sind gleich.");
  1806. }
  1807.  
  1808. lauten, damit das gemacht wird, was eigentlich gewⁿnscht ist.
  1809.  
  1810.  
  1811. Im Zusammenhang mit Strings ist noch eine Besonderheit zu erwΣhnen:
  1812.  
  1813. if ("Java".equals(stringZwei)) {
  1814.     System.out.println("stringZwei ist gleich zu Java.");
  1815. }
  1816.  
  1817. ist zulΣssig, der Compiler erzeugt aus
  1818. der Zeichenkette automatisch ein String-Objekt; man mu▀ also nicht
  1819. zuerst ein Objekt anlegen und den String Java dort speichern.
  1820.  
  1821.  
  1822. 3.2.2. Wie wandle ich einen String in einen Integer?
  1823.        Autor: Markus Reitz
  1824. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1825. Klassen k÷nnen Methoden besitzen, die die Konvertierung eines Objekts
  1826. dieser Klasse in ein Objekt einer anderen Klasse ⁿbernehmen. Zu dem
  1827. elementaren Java-Datentyp int gibt es eine sogenannte Wrapper-Klasse
  1828. Integer, die den elementaren Datentyp in einer Klasse kapselt .Diese
  1829. Klasse stellt eine Methode (in diesem Fall eine Klassenmethode) zur
  1830. Verfⁿgung, die das Gewⁿnschte leistet:
  1831.  
  1832. public class Test {
  1833.     public static void main (String[] params) {
  1834.         String stringMitZahl = "50";
  1835.         int zahl = 0;
  1836.         try {
  1837.             zahl = Integer.parseInt(stringMitZahl);
  1838.         } catch (NumberFormatException e) {
  1839.             e.printStackTrace();
  1840.         }
  1841.         zahl = zahl + 10;
  1842.         System.out.println("Die Variable zahl = " + zahl);
  1843.     }
  1844. }
  1845.  
  1846.  
  1847. 3.2.3. Wie wandle ich einen Integer in einen String um?
  1848.        Autor: Markus Reitz
  1849. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1850. Dieses Problem ist genau das Gegenteil des vorherigen. Wie die Klasse
  1851. Integer, so besitzt auch die Klasse String eine Methode, die das
  1852. Problem l÷st, allerdings hei▀t die Methode nicht parseString, was man
  1853. analog schlie▀en k÷nnte, sondern valueOf.
  1854.  
  1855. public class Test {
  1856.     public static void main (String[] params) {
  1857.         int zahl = 50;
  1858.         String stringMitZahl = String.valueOf(zahl);
  1859.         System.out.println("Die Variable stringMitZahl = " +
  1860.                 stringMitZahl);
  1861.     }
  1862. }
  1863.  
  1864.  
  1865. 3.2.4. Wie wandle ich einen Integer in einen HexString um?
  1866.        Autor: Uwe Gⁿnther
  1867. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1868. Das Problem ist Σhnlich wie das Konvertieren von einem Integer in einen
  1869. String. Wie die Klasse String die Klassenmethode valueOf besitzt, um
  1870. einen String zu erzeugen, so besitzt die Klasse Integer die
  1871. Klassenmethode toHexString(int i).
  1872.  
  1873. public class Test {
  1874.     public static void main (String[] params) {
  1875.         int zahl = 50;
  1876.         String stringAlsHex = Integer.toHexString(zahl);
  1877.         System.out.println("Die Variable stringAlsHex = " +
  1878.                            stringAlsHex);
  1879.     }
  1880. }
  1881.  
  1882. Der Nachteil der Integer.toHexString(int i) Methode ist, dass sie alle
  1883. fⁿhrenden Nullen einer Hex-ReprΣsentation abschneidet.
  1884.  
  1885.  
  1886. 3.2.5. Wie kann ich eine Zahl formatieren und wie lege ich die Anzahl der
  1887.        Nachkommastellen fest?
  1888.        Autor: Karsten Schulz
  1889. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1890. Das kann die Klasse java.text.NumberFormat und deren Abk÷mmlinge
  1891. erledigen.
  1892.  
  1893. Beispiel:
  1894.  
  1895. import java.text.DecimalFormat;
  1896.  
  1897. public class Zahl {
  1898.     public static void main(String[] args) {
  1899.         double betrag = 1000d/3d; // -> 333.333333...
  1900.         DecimalFormat df = new DecimalFormat("#.##");
  1901.         System.out.println(df.format(betrag));
  1902.         df = new DecimalFormat("#.## DM");
  1903.         System.out.println(df.format(betrag));
  1904.         df = new DecimalFormat("0000.0000");
  1905.         System.out.println(df.format(betrag));
  1906.     }
  1907. }
  1908.  
  1909. Die Ausgabe des Programms sind formatierte Dezimalzahlen:
  1910. 333,33
  1911. 333,33 DM
  1912. 0333,3333
  1913.  
  1914. In der API-Dokumentation der Klassen java.text.Decimalformat und
  1915. java.text.NumberFormat werden alle weiteren Formatierungsoptionen
  1916. erlΣutert. Falls die Umwandlungen von double nach String
  1917. zeitkritisch durchgefⁿhrt werden mⁿssen, lohnt sich ein Blick auf
  1918. <URL:http://www.onjava.com/pub/a/onjava/2000/12/15/formatting_doubles.html>
  1919. Dort erklΣrt Jack Shirazi (Autor des Buches "Java Perfomance Tuning")
  1920. andere Konvertierungsmethoden.
  1921.  
  1922.  
  1923. 3.2.6. Wie kann ich ein Datum formatieren?
  1924.        Autor: Karsten Schulz
  1925. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1926. Das machen andere fⁿr Dich,...
  1927.  
  1928. Benutze einfach die Klassen DateFormat aus dem package java.text.
  1929. Folgendes Beispiel zeigt Dir die Anwendung der SimpleDateFormat-Klasse:
  1930.  
  1931. import java.util.Date;
  1932. import java.text.SimpleDateFormat;
  1933.  
  1934. public class Datum {
  1935.     public static void main(String[] args) {
  1936.         SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
  1937.         System.out.println(sd.format(new Date()));
  1938.         sd.applyPattern("dd.MM.yyyy");
  1939.         System.out.println(sd.format(new Date()));
  1940.     }
  1941. }
  1942.  
  1943. Die Ausgabe des Programms sind formatierte Datⁿmer:
  1944.  
  1945.     2000-12-24
  1946.     24.12.2000
  1947.  
  1948. In der API-Dokumentation zur Klasse java.text.SimpleDateFormat sind die
  1949. Kⁿrzel der verschiedenen Datumskomponenten fⁿr Tag, Monat, usw.
  1950. aufgefⁿhrt.
  1951.  
  1952.  
  1953. 3.2.7. Wie kann ich in einem String oder StringBuffer mehrere Zeichen
  1954.        suchen und ersetzen?
  1955.        Autor: Martin Erren
  1956. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1957. Mit
  1958.  
  1959.     String String#replace(char,char)
  1960.  
  1961. kann ich nur einzelne Zeichen suchen und mit
  1962.  
  1963.     StringBuffer replace(int,int,String)
  1964.  
  1965. nur ersetzen aber nicht suchen.
  1966.  
  1967. L÷sung:
  1968.  
  1969. Eine gute Hausaufgabe. Was man hier braucht, ist eine Kombination von
  1970.  
  1971.     int String#indexOf(String,int),
  1972.     String String#substring(int,int)
  1973.  
  1974. mit einem neu aufzubauenden StringBuffer.
  1975.  
  1976. bzw.
  1977.  
  1978.     int StringBuffer#indexOf(String,int)
  1979.     StringBuffer#replace(int,int,String)
  1980.  
  1981.  
  1982. Die folgende L÷sung ist eine unter vielen und ersetzt alle Vorkommen von
  1983. "search" in "source" mit "replace":
  1984.  
  1985. public static String replaceAll(String source, String search,
  1986.                                 String replace) {
  1987.     if(search.equals(replace)) {
  1988.         return source; //kann ja sein, dass wir nichts tun mⁿssen
  1989.     }
  1990.  
  1991.     StringBuffer result = new StringBuffer();
  1992.     int len = search.length();
  1993.     if(len == 0) {
  1994.         return source; //verhindert Endlosschleife bei search.equals("");
  1995.     }
  1996.  
  1997.     int pos = 0; //position
  1998.     int nPos;    //next position
  1999.     do {
  2000.         nPos = source.indexOf(search, pos);
  2001.         if(nPos != -1) { //gefunden
  2002.             result.append(source.substring(pos, nPos));
  2003.             result.append(replace);
  2004.             pos = nPos+len;
  2005.         } else { //nicht gefunden
  2006.             result.append(source.substring(pos)); //letzter abschnitt
  2007.         }
  2008.     } while(nPos!= -1);
  2009.  
  2010.     return result.toString();
  2011. }
  2012.  
  2013. Da sowas praktisch ⁿberall gebraucht wird, gibt es unzΣhlige
  2014. Bibliothek(chen) im Netz, die so etwas anbieten, z.B.
  2015.  
  2016. <URL:http://ostermiller.org/utils/StringHelper.java.html>
  2017.  
  2018. BTW: Der Link muss as den 3 Zeilen zusammen gestzt werden!
  2019.  
  2020. [...vielleicht noch mehr und geeignetere Adressen...]
  2021.  
  2022.  
  2023.  
  2024. 3.2.8. Gibt es regulΣre Ausdrⁿcke in Java (regular expressions)?
  2025.        Autor: Karsten Schulz
  2026. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2027. Ja, natⁿrlich.
  2028.  
  2029. Bis zum J2SDK 1.4 muss man, um regulΣre Ausdrⁿcke in Java zu benutzen,
  2030. auf externe packages zurⁿckgreifen. Eines der ausgereiftesten ist das
  2031. Regexp-Paket aus dem Jakarta-Projekt:
  2032.  
  2033.     http://jakarta.apache.org/regexp/index.html
  2034.  
  2035. Ab dem J2SDK 1.4 wird es jedoch ein package java.util.regex geben, das
  2036. somit die M÷glichkeit zur Benutzung der regulΣren Ausdrⁿcke direkt in die
  2037. Klassenhierarchie einbaut.
  2038.  
  2039. Nachfolgend ein Beispiel fⁿr die Nutzung dieses packages (Achtung:
  2040. funktioniert nur ab J2SDK 1.4 aufwΣrts!).
  2041.  
  2042. Das Beispielprogramm zeigt, wie in der Stringvariablen 'input'
  2043. nach einem Muster (Pattern) gesucht wird, das auf einer Ziffer,
  2044. mindestens einem Buchstaben und einer weiteren Ziffer besteht:
  2045.  
  2046. import java.util.regex.Matcher;
  2047. import java.util.regex.Pattern;
  2048.  
  2049. public class PatternTest {
  2050.  
  2051.     public static void main(String[] args) {
  2052.         String input = "Test fⁿr Regex Ausdrⁿcke 1xxx2 n444n.";
  2053.         Pattern p = Pattern.compile("\\d\\D+\\d");
  2054.         // Muster: Ziffer, mind. ein Buchstabe, Ziffer
  2055.         Matcher m = p.matcher(input);
  2056.         if (m.find()) {
  2057.             System.out.println("Muster an Pos. " + m.start());
  2058.                 System.out.println("Muster ist: " + m.group());
  2059.         } else {
  2060.             System.out.println("Muster nicht gefunden");
  2061.         }
  2062.     }
  2063. }
  2064.  
  2065. Die Ausgabe dieses Programms ist:
  2066.  
  2067.     Muster an Pos. 25
  2068.     Muster ist: 1xxx2
  2069.  
  2070. Weitere Infos in der API-Dokumentation zu java.util.regex.
  2071.  
  2072.  
  2073.  
  2074.  
  2075. 3.3. [IO] - Frage bezⁿglich Eingabe/Ausgabe, Streams, etc. in Java.
  2076. -------------------------------------------------------------------
  2077.  
  2078. 3.3.1. Verlangsamt Serialisierung mein Programm?
  2079.        Autor: Markus Reitz
  2080. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2081. Java bietet mit dem Mechanismus der Serialisierung auf einfache Weise
  2082. die M÷glichkeit, den aktuellen Zustand des Objekts auf einem
  2083. DatentrΣger, das Netz oder sonst wohin ⁿber einen Stream zu sichern. Der
  2084. verwendete Mechanismus ist relativ kompliziert, damit auch alle
  2085. auftretenden M÷glichkeiten korrekt behandelt werden k÷nnen. Sind die
  2086. Daten der Objekte sehr gro▀, so empfiehlt es sich, eigene Prozeduren
  2087. zur Speicherung zu entwickeln, die dann nicht mehr allgemeingⁿltig, aber
  2088. auf die aktuelle Verwendung angepa▀t und damit schneller sind.
  2089.  
  2090.  
  2091. 3.3.2. Wie kann ich rekursiv einen Verzeichnisbaum abarbeiten?
  2092.        Autor: Marco Schmidt
  2093. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2094.  
  2095. In java.io.File befinden sich die dazu ben÷tigte FunktionalitΣt. Mit
  2096. list() lΣ▀t man sich ein Array mit allen Dateinamen geben, mit
  2097. isDirectory() lΣ▀t sich prⁿfen, ob es sich bei dem File-Objekt um ein
  2098. Verzeichnis handelt. Indem man nun rekursiv in Unterverzeichnisse
  2099. absteigt, kann man so einen kompletten Verzeichnisbaum abarbeiten.
  2100.  
  2101. Hier ein Beispielprogramm (scantree.java):
  2102.  
  2103. import java.io.File;
  2104.  
  2105. public class scantree {
  2106.     public static void main(String[] args) {
  2107.         // Programm muss einen Verzeichnisnamen als Parameter haben
  2108.         File dir = new File(args[0]);
  2109.         scan(dir);
  2110.     }
  2111.  
  2112.     public static void scan(File dir) {
  2113.         // Liste aller Dateien und Unterverzeichnisse holen
  2114.         String[] entries = dir.list();
  2115.         if (entries == null || entries.length < 1) {
  2116.             return;
  2117.         }
  2118.         for (int i = 0; i < entries.length; i++) {
  2119.             File entry = new File(dir, entries[i]);
  2120.             if (entry.isDirectory()) {
  2121.                 scan(entry); // rekursiv ins Unterverzeichnis verzweigen
  2122.             } else {
  2123.                 // entry ist eine Datei
  2124.                 System.out.println(entry);
  2125.             }
  2126.         }
  2127.     }
  2128. }
  2129.  
  2130.  
  2131. 3.3.3. Wie kann ich aus Dateien zeilenweise lesen?
  2132.        Autor: Markus Reitz
  2133. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2134. Generell nutzt man fⁿr die Datei-Operationen einen Buffered Reader oder
  2135. eine Klasse, die von dieser abstammt. Diese Klasse besitzt dann die
  2136. Methode readLine(), die eine Zeile aus der Datei ausliest und diese Zeile
  2137. als einen String zurⁿckgibt.
  2138.  
  2139. Zu beachten ist, da▀ bei Erreichen des Dateiendes kein leerer String,
  2140. sondern eine Nullreferenz zurⁿckgegeben wird. Ein Programm, da▀ aus einer
  2141. Datei zeilenweise liest, sieht in Java wie folgt aus:
  2142.  
  2143. import java.io.*;
  2144.  
  2145. public class ZeilenWeiseLesen {
  2146.     public static void main(String[] args) {
  2147.         try {
  2148.             String zeile;
  2149.  
  2150.             //Wir lesen aus "eingabe.txt".
  2151.             File eingabeDatei = new File("eingabe.txt");
  2152.             FileReader eingabeStrom = new FileReader(eingabeDatei);
  2153.             BufferedReader eingabe = new BufferedReader(eingabeStrom);
  2154.  
  2155.             while ((zeile = eingabe.readLine()) != null) {
  2156.                 System.out.println(zeile);
  2157.             }
  2158.         } catch (IOException e) {
  2159.             e.printStackTrace();
  2160.         }
  2161.     }
  2162. }
  2163.  
  2164.  
  2165. 3.3.4. Wie kann ich Exponentialzahlen (z.B. 1.09E+008) aus einer Datei
  2166.        lesen?
  2167.        Autor: Wolfram Rⁿhaak
  2168. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2169. Mit Java fⁿhrt folgendes Verfahren zum Ziel:
  2170. Lies die Daten als Strings ein und wandel sie mittels
  2171. Double.valueOf(my_string).doubleValue()
  2172. in einen double Wert um.
  2173.  
  2174. Das StreamTokenizer keine Exponentialzahlen kennt hat von Sun Bug Status
  2175. bekommen (obgleich der StreamTokenizer so arbeitet wie angegeben):
  2176. * BugId: #4079180
  2177.   Synopsis:  java.io.StreamTokenizer: Add ability to read full Java
  2178.   floating-point syntax
  2179.   Der Sun Workaround soll wohl ein:
  2180.       public void parseExponentialNumbers(boolean flag)
  2181.    sein.
  2182.  
  2183. Beispiel:
  2184. import java.io.*;
  2185. import java.util.Vector;
  2186. /**
  2187.  * @author Wolfram Rⁿhaak
  2188.  * Beispielcode, der zeigt wie man Zahlen aus einer Datei liest.
  2189.  * Die Datei darf in diesem Fall nur Zahlen enthalten, getrennt durch
  2190.  * Tabulator oder Space.
  2191.  * Die Anzahl von Spalten/Zeilen ist nicht vorgegeben.
  2192.  * Um *.cvs KompatibilΣt zu erhalten kann man als whitespaceChars
  2193.  * noch ',' und ';' hinzufⁿgen.
  2194.  */
  2195. public class ReadExponential {
  2196.  
  2197.     int ni; // Anzahl Zeilen
  2198.     int nj; // Anzahl Spalten
  2199.  
  2200.      private ReadExponential(String Filename) {
  2201.          int i=0;
  2202.          int j=0;
  2203.          Vector v2 = new Vector();
  2204.  
  2205.          try {
  2206.              FileInputStream fis = new FileInputStream(Filename);
  2207.              BufferedReader r =
  2208.                      new BufferedReader(new InputStreamReader(fis));
  2209.              StreamTokenizer st  = new StreamTokenizer(r);
  2210.              /*
  2211.               * Nachfolgendes Code-Fragment von:
  2212.               * Mark Gritter (mgritter@pup16.stanford.edu)
  2213.               * Betrifft:Re: This is easy in C++ (asking for help)
  2214.               * Newsgroups:comp.lang.java.programmer
  2215.               * Datum:1997/11/07
  2216.               */
  2217.              st.resetSyntax();
  2218.              st.whitespaceChars(' ', ' ');
  2219.              st.whitespaceChars('\n', '\n');
  2220.              st.wordChars('0','9');
  2221.              st.wordChars('e','e');
  2222.              st.wordChars('E','E');
  2223.              st.wordChars('.','.');
  2224.              st.wordChars('+','+');
  2225.              st.wordChars('-','-');
  2226.              /* Ende Code-Fragment */
  2227.             st.eolIsSignificant(true);
  2228.  
  2229.             try {
  2230.                 while(st.nextToken() != st.TT_EOF) {
  2231.                     String s1 = st.sval;
  2232.                     if(s1!=null) {
  2233.                         // Wert in Vector schreiben
  2234.                         v2.addElement(s1);
  2235.                         // Anzahl von Zeilen
  2236.                         i=st.lineno();
  2237.                     }
  2238.                 }
  2239.             } catch(IOException ioe) {}
  2240.         } catch (FileNotFoundException fnfe) {}
  2241.         ni = i - 1;
  2242.         nj = ((v2.size())/(ni+1))-1;   // Anzahl von Spalten berechnen
  2243.  
  2244.         double[][] dAllValues = new double [ni+1][nj+1];
  2245.         int k=0;
  2246.         for(i = 0;i <= ni; i++) {
  2247.             for(j = 0;j <= nj; j++) {
  2248.                 Object f = v2.elementAt(k); // Vector in
  2249.                 String s = f.toString();    // Array umspeichern
  2250.                 /*
  2251.                  * Double.valueOf(String s) kann jeden numerischen Wert
  2252.                  * von String nach double umwandeln
  2253.                  */
  2254.                 dAllValues[i][j] = Double.valueOf(s).doubleValue();
  2255.                 k++;
  2256.             }
  2257.         }
  2258.     }
  2259. }
  2260.  
  2261.  
  2262.  
  2263.  
  2264. 3.3.5. Wie kann ich mit Java Dateien kopieren?
  2265.        Autor: Martin Erren, Uwe Gⁿnther, Ulf JΣhrig, Christian Kaufhold
  2266. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2267. Bestimmt die performanteste L÷sung wΣre, mit
  2268.  
  2269.  System.exec(...)
  2270.  
  2271. die Aufgabe dem Betriebssystem zu ⁿbergeben.
  2272.  
  2273. Der Nachteil ist hier, dass so schwer ein plattformunabhΣngiger
  2274. Code erreichbar ist und die Fehlerbehandlung schwierig wird.
  2275.  
  2276. Deshalb einfach eine Datei lesen und in eine andere, neue
  2277. Datei schreiben, z.B. so:
  2278.  
  2279. import java.io.*;
  2280.  
  2281. public static void copyFile(File src, File dest, int bufSize,
  2282.         boolean force) throws IOException {
  2283.     if(dest.exists()) {
  2284.         if(force) {
  2285.             dest.delete();
  2286.         } else {
  2287.             throw new IOException(
  2288.                     "Cannot overwrite existing file: " + destName);
  2289.         }
  2290.     }
  2291.     byte[] buffer = new byte[bufSize];
  2292.     int read = 0;
  2293.     InputStream in = null;
  2294.     OutputStream out = null;
  2295.     try {
  2296.         in = new FileInputStream(src);
  2297.         out = new FileOutputStream(dest);
  2298.         while(true) {
  2299.             read = in.read(buffer);
  2300.             if (read == -1) {
  2301.                 //-1 bedeutet EOF
  2302.                 break;
  2303.             }
  2304.             out.write(buffer, 0, read);
  2305.         }
  2306.     } finally {
  2307.         // Sicherstellen, dass die Streams auch
  2308.         // bei einem throw geschlossen werden.
  2309.         // Falls in null ist, ist out auch null!
  2310.         if (in != null) {
  2311.             //Falls tatsΣchlich in.close() und out.close()
  2312.             //Exceptions werfen, die jenige von 'out' geworfen wird.
  2313.             try {
  2314.                 in.close();
  2315.             }
  2316.             finally {
  2317.                 if (out != null) {
  2318.                     out.close();
  2319.                 }
  2320.             }
  2321.         }
  2322.     }
  2323. }
  2324.  
  2325.  
  2326. Das schwierigste ist hier wohl die Fehlerbehandlung, die je nach
  2327. Anforderung unterschiedlich sein kann.
  2328.  
  2329. Anmerkung: Ein paar exotische VMs optimieren read(byte[]) bzw.
  2330. write(byte[]) nicht, so dass hier ein BufferedInputStream oder
  2331. BufferedOutputStream evtl. angebracht ist.
  2332.  
  2333.  
  2334. 3.3.6. Wie kann man auf programmnahe Resourcen (Button-images,
  2335.        local String properties,...) zugreifen, ohne absolut oder relativ
  2336.        zu user.dir adressieren zu mⁿssen (ich will das ganze auch in ein
  2337.        jar packen k÷nnen)?
  2338.        Autor: Martin Erren
  2339. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2340.     URL Class#getResource(String)
  2341.  
  2342. und
  2343.  
  2344.     InputStream Class#getResourceAsStream(String)
  2345.  
  2346. sind Deine Freunde. Laut API-doc ist "/img.jpg" relativ zur codeBase,
  2347. also dem aktuellen Eintrag im CLASSPATH, wo Deine Klasse geladen wurde,
  2348. und "img.jpg" relativ zur Klasse, also im selben Verzeichnis, wo auch
  2349. die Klasse liegt.
  2350.  
  2351. Ob Applikation oder Applet, *.jar oder file-system spielt hier keine
  2352. Rolle.
  2353.  
  2354. mit
  2355.  
  2356.     System.out.println(MyClass.class.getResource("/").toString());
  2357.  
  2358. kannst Du jederzeit feststellen, welche codebase die jeweilige Klasse
  2359. hat.
  2360.  
  2361. Weiterhin sind
  2362.  
  2363.     InputStream ClassLoader.getSystemResourceAsStream(name);
  2364.  
  2365. und
  2366.  
  2367.     URL ClassLoader.getSystemResource(name)
  2368.  
  2369. fⁿr eigene Resourcen nicht zu empfehlen.
  2370.  
  2371. [Hier fehlt die Begrⁿndung]
  2372.  
  2373.  
  2374.  
  2375.  
  2376. 3.4. [NET] - Frage bezⁿglich Netzwerk.
  2377. --------------------------------------
  2378.  
  2379. 3.4.1. Wie kann ich einen Ping in Java realisieren?
  2380.        Autor: Stephan Menzel
  2381. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2382. Eigentlich gar nicht. Ein Ping (ICMP) ist eine hardwarenahe
  2383. Angelegenheit, die im Gegensatz zu dem hardwarefernen abstrahierenden
  2384. Konzept von Java steht. Die Antworten einer Netzwerkkarte sind da nicht
  2385. so sehr relevant, wie ein im Netzwerk vorhandener Dienst. So kann zum
  2386. Beispiel ein Rechner auf Pings nicht antworten und trotzdem einen Dienst
  2387. anbieten. Oder die Pings verenden an einer Firewall oder aber der Rechner
  2388. auf dem das Programm laeuft, ist gar nicht in der Lage, zu pingen.
  2389. Das bedeutet, es ist sicherer und besser, einfach eine Testweise
  2390. Socketverbindung zu der betreffenden Zieladresse aufzubauen und eine
  2391. evtl. auftretende Exception als Zeichen fuer dessen Abwesenheit im Netz
  2392. zu deuten.
  2393.  
  2394. Folgendes Beispiel soll dies zeigen:
  2395.  
  2396. import java.io.*;
  2397. import java.net.*;
  2398. ..
  2399.  
  2400.  static Socket nntpsock; // Der Socket fuer die Newsverbindung
  2401.  static BufferedReader in;
  2402.  static OutputStreamWriter out;
  2403.  
  2404. ...
  2405.  
  2406. try {
  2407.     nntpsock = new Socket("news.cis.dfn.de", 119); // Verbinden
  2408.     nntpsock.setSoTimeout(300); // Timeout auf 300ms
  2409.     in = new BufferedReader(
  2410.             new InputStreamReader(nntpsock.getInputStream()));
  2411.     out = new OutputStreamWriter(nntpsock.getOutputStream());
  2412. } catch (UnknownHostException e) {
  2413.     System.err.println("Unknown Host.:" + e.toString());
  2414. } catch (IOException e) {
  2415.     System.err.println("Rechner nicht erreichbar.  :" + e.toString());
  2416. }
  2417.  
  2418. ...
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425. 3.5. [AWT] - Frage bezⁿglich AWT.
  2426. ---------------------------------
  2427.  
  2428. 3.5.1 Wenn ich einen Listener bei mehreren Buttons anmelde, wie kann ich
  2429.       dann unterscheiden, welcher gedrⁿckt wurde?
  2430.       Autor: Michael Paap, Christian Kaufhold, Georg Lippitsch
  2431. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2432. Wenn Du so vorgehst wird, egal welcher Button geclickt wird, die Methode
  2433. actionPerformed(ActionEvent ev) des Listeners aufgerufen.
  2434.  
  2435. Mit ev.getSource() bekommst Du nun eine Referenz auf die Ereignisquelle
  2436. (als Object). Dann kannst Du schauen, welcher Button geclickt wurde,
  2437. z.B. indem Du diese Ereignisquelle mit den vorhandenen Buttons
  2438. vergleichst oder indem Du auf Button castest und ihre Beschriftung
  2439. ausliest.
  2440.  
  2441. Beispiel:
  2442.  
  2443. Angenommen, Du hast einen ActionListener bei jedem Button
  2444. eines Arrays von 4 Buttons registriert. Dann k÷nnte die
  2445. Methode actionPerformed im Listener wie folgt aussehen:
  2446.  
  2447. public void actionPerformed(ActionEvent ev) {
  2448.     int pressed = -1;
  2449.     for (int i=0; i<myButtons.length; i++) {
  2450.         if (myButtons[i] == ev.getSource()) {
  2451.             pressed = i;
  2452.             break;
  2453.         }
  2454.     }
  2455.  
  2456.     // hier abhΣngig von pressed verschiedene Aktionen
  2457.     // ausfⁿhren
  2458. }
  2459.  
  2460. oder so:
  2461.  
  2462. public void actionPerformed(ActionEvent ev) {
  2463.     Button pressed = (Button) ev.getSource();
  2464.     System.out.println("Pressed: " + pressed.getLabel());
  2465. }
  2466.  
  2467.  
  2468. Eine weitere M÷glichkeit bietet die Methode
  2469.  
  2470.     Button#setActionCommand(String command)
  2471.  
  2472. Hiermit kann ein dem Knopf ein beliebiger String zugewiesen. Dieser kann
  2473. mit
  2474.  
  2475.     ActionEvent#getActionCommand()
  2476.  
  2477. wieder abgefragt werden. Dabei wird immer der String zurⁿckgegeben, der
  2478. dem Event ausl÷senden Knopf zugewiesen wurde.
  2479.  
  2480. Ein Beispiel:
  2481.  
  2482. Button knopf1 = new Button("Max");
  2483. knopf1.setActionKommand("schlimmer bub 1");
  2484. Button knopf2 = new Button("Moritz");
  2485. knopf2.setActionKommand("schlimmer bub 2");
  2486.  
  2487. public void actionPerformed(ActionEvent ev) {
  2488.     String c = ev.getActionCommand();
  2489.     if (c.equals("schlimmer bub 2"))
  2490.         System.out.println("Moritz wurde aktiviert");
  2491. }
  2492.  
  2493.  
  2494.  
  2495.  
  2496. 3.5.2. Kann ich ein Fenster (Frame/JFrame) maximieren?
  2497.        Autor: Karsten Schulz
  2498. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2499. Antwort: Jein.
  2500.  
  2501. Bis zum J2SDK 1.3 (einschlie▀lich) gibt es keine M÷glichkeit, ein
  2502. Fenster zu maximieren. Es gibt nur verschiedene Workarounds, um ein
  2503. Fenster m÷glichst flΣchendeckend auf dem Desktop darzustellen (s.u.)
  2504.  
  2505. Ab dem J2SDK1.4 gibt es die Methode setExtendedState(int state) aus
  2506. der Klasse java.awt.Frame, mit der das Fenster *vielleicht*
  2507. maximiert wird. Ob das m÷glich ist, kann mittels
  2508. isFrameStateSupported(int state) aus dem Toolkit ermittelt werden,
  2509. denn nicht jede Plattform unterstⁿtzt solche maximierten Fenster.
  2510.  
  2511. Fⁿr Anwendungen, die mittels einer J2SDK-Version bis 1.3 erstellt werden
  2512. sollen, gibt es nur Workarounds, da es eine "Maximieren"-Funktion
  2513. nicht gibt. Fⁿr den Windows-Benutzer mag das merkwⁿrdig sein, fⁿr
  2514. den Unix-Benutzer ist der Gedanke merkwⁿrdig, dass die tatsΣchliche
  2515. Bildschirmgr÷sse etwas mit der Desktopgr÷▀e zu tun haben sollte.
  2516.  
  2517. Lange Rede, kurzer Code:
  2518. um ein Fenster m÷glichst gro▀ zu machen, nehme man
  2519.   setSize(getToolkit().getScreenSize());
  2520.  
  2521. Hierdurch wird das darzustellende Fenster vielleicht auf die Gr÷▀e
  2522. der aktuellen Bildschirmaufl÷sung gesetzt. Ohne Berⁿcksichtigung
  2523. evtl.  darzustellender Menⁿ- und/oder Taskleisten.
  2524.  
  2525. Falls auf der Laufzeitplattform ein ÷ffnendes Programmfenster von
  2526. einem Fenstermanager platziert wird, hat die setSize(Dimension)-Methode
  2527. m÷glicherweise keine Auswirkung auf das Fenster. Der Programmierer sollte
  2528. sich also nicht darauf verlassen, dass sein Fenster so dargestellt wird,
  2529. wie er es programmiert hat!
  2530.  
  2531. Eine weitere M÷glichkeit, ein Fenster evtl. zu maximieren besteht
  2532. darin, die Klasse java.awt.Robot (seit J2SDK 1.3) zu benutzen, um die
  2533. Maximieren-SchaltflΣche programmgesteuert anklicken zu lassen.
  2534. Hinweise zur Benutzung dieser Klasse finden sich im JDC Tech Tip
  2535. vom 11. Juli 2000
  2536. <URL:http://developer.java.sun.com/developer/TechTips/2000/tt0711.html)
  2537.  
  2538. Wegen dieser ganzen UnwΣgbarkeiten ist es oft eine Alternative, statt
  2539. das Fenster zu maximieren, es einfach Wiederherzustellen und die Gr÷▀e
  2540. und Position des Fensters von einem vorherigen Programmlauf zu benutzen.
  2541. Hierbei sollte jedoch darauf geachtet werden, dass die Geometrie eines
  2542. maximierten Fensters *nicht* durch ein normales Fenster nachgebildet
  2543. wird, weil der Anwender sonst dadurch verwirrt wird, dass das Fenster
  2544. maximiert aussieht, es aber in Wirklichkeit nicht ist!
  2545.  
  2546.  
  2547. 3.5.3. Wie tausche ich die Kaffeetasse im blauen Balken aus?
  2548.        Autor: Karsten Schulz, Roger Schuster, Christian Wederhake
  2549. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2550. Das geht mit java.awt.Frame#setIconImage(java.awt.Image).
  2551.  
  2552. Beispiel:
  2553.  
  2554.     ImageIcon icon = new ImageIcon("meinBildchen.gif");
  2555.     setIconImage(icon.getImage());
  2556.  
  2557.  
  2558. 3.6. [SWING] - Frage bezⁿglich Swing.
  2559. -------------------------------------
  2560.  
  2561. 3.6.1. Wie mache ich globale Font-─nderung fⁿr meine Komponenten?
  2562.        Autor: Linda Radecke
  2563. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2564. Das geht mit:
  2565.  
  2566. * UIManager.put("component.font", new FontUIResource(...));
  2567.  
  2568.  
  2569. 3.6.2. Wie kann ich bei der Eingabe in ein JTextField die Anzahl
  2570.        der eingebbaren Zeichen beschrΣnken?
  2571.        Autor: Alexander Elsholz
  2572. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2573. Wenn ein JTextField benutzt wird sollte man ein
  2574. benutzerdefiniertes Document implementieren. Fⁿr
  2575. AWT-Textfelder funktioniert es mit einigen Anpassungen
  2576. auch ⁿber das Interface KeyListener.
  2577.  
  2578.  
  2579. import javax.swing.text.PlainDocument;
  2580. import javax.swing.text.BadLocationException;
  2581. import javax.swing.text.AttributeSet;
  2582.  
  2583. /**
  2584.  * Diese Klasse ist ein Dokument fⁿr Textfelder, welches die Eingabe auf
  2585.  * x Zeichen begrenzt.
  2586.  *
  2587.  * Die Zuweisung geschieht ⁿber
  2588.  * JTextfield.setDocument(new Validation(int anzahl));
  2589.  */
  2590. public class Validation extends PlainDocument{
  2591.     private int limit;
  2592.  
  2593.      /**
  2594.       * Konstruktor fⁿr das Validationdokument
  2595.       * @param int limit: maximale Anzahl der einzugebenen Zeichen
  2596.       */
  2597.      public Validation(int newLimit){
  2598.          super();
  2599.          if (limit < 0){
  2600.              limit = 0;
  2601.          } else {
  2602.              limit = newLimit;
  2603.          }
  2604.      }
  2605.  
  2606.     /**
  2607.      * Funktion ⁿberschreibt die Methode insertString von PlainDocument
  2608.      * @param int offset: Position
  2609.      * @param String str: der String
  2610.      * @param AttributeSet attr: Attributset
  2611.      */
  2612.     public void insertString (int offset, String str, AttributeSet attr)
  2613.             throws BadLocationException {
  2614.         if (str == null) return;
  2615.  
  2616.         if ((getLength() + str.length()) <= limit){
  2617.             super.insertString(offset, str, attr);
  2618.         }
  2619.      }
  2620. }
  2621.  
  2622. Die hier aufgezeigte L÷sung zur Begrenzung von Textfeldern kann auch
  2623. verwendet werden, wenn unerwⁿnschte Zeichen in einem Textfeld nicht
  2624. eingegeben werden dⁿrfen.
  2625.  
  2626.  
  2627. 3.6.3. Wie setze ich den Cursor an den Anfang der JTextArea?
  2628.        Autor: Linda Radecke
  2629. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2630. Das geht mit:
  2631.  
  2632. * textarea.setCaretPosition(0);
  2633.  
  2634.  
  2635. 3.6.4. Wie scrolle ich an das Ende der JTextArea?
  2636.        Autor: Linda Radecke
  2637. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2638. Hierzu existieren mehrere M÷glichkeiten:
  2639.  
  2640. * textarea.setCaretPosition(textarea.getDocument().getLength());
  2641.  
  2642. * try{
  2643.  
  2644.   textarea.scrollRectToVisible(textarea.modelToView(
  2645.                            textarea.getDocument().getLength()));
  2646.  
  2647.   } catch (BadLocationException be) {
  2648.            be.toString();
  2649. }
  2650.  
  2651. * (Geht auch, weniger sch÷n): mit getText().length();
  2652.  
  2653.  
  2654. Scrolling wrappen in SwingUtilities.invokeLater(), bspw:
  2655.  
  2656. SwingUtilities.invokeLater(new Runnable() {
  2657.  
  2658.    public void run() {
  2659.  
  2660.    // scrolling code
  2661.  
  2662.   }
  2663. };
  2664.  
  2665.  
  2666. 3.6.5. Wie bekomme ich es hin, das der Benutzer in meiner JTable
  2667.        keine Eingaben tΣtigen kann?
  2668.        Autor: Alexander Elsholz
  2669. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2670. Das funktioniert ⁿber das Tabellenmodell deiner JTable:
  2671.  
  2672. import javax.swing.table.DefaultTableModel
  2673.  
  2674. /**
  2675.  * Diese Klasse reprΣsentiert das Datenmodell fⁿr eine oder mehrere
  2676.  * Tabellen
  2677.  *
  2678.  * Die Zuweisung geschieht ⁿber JTable.setModel(new YourTableModel()));
  2679.  */
  2680. public class YourTableModel extends DefaultTableModel {
  2681.  
  2682.     /**
  2683.      * aus der API: Returns true if the cell at rowIndex and columnIndex
  2684.      * is editable. Otherwise, setValueAt on the cell will not change the
  2685.      * value of that cell.
  2686.      */
  2687.     public boolean isCellEditable(int row, int column) {
  2688.         return false;
  2689.     }
  2690. }
  2691.  
  2692. Dieses Bespiel verhindert das Editieren von zellen in allen Zellen der
  2693. Tabelle, durch Auswerten der Parameter k÷nn aber auch einzelne Spalte,
  2694. Zeilen oder Zellen gesperrt werden.
  2695.  
  2696.  
  2697. 3.6.6. Wie bekomme ich eine horizontale ScrollBar bei JTable?
  2698.        Autor: Linda Radecke
  2699. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2700. Das geht mit:
  2701.  
  2702. * table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
  2703.  
  2704.  
  2705. 3.6.7. Wie scrolle ich ans Ende von JTable?
  2706.        Autor: Linda Radecke
  2707. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2708. Das geht mit:
  2709.  
  2710. * table.scrollRectToVisible(table.getCellRect(
  2711.                             table.getRowCount()-1,-1,true));
  2712.  
  2713.  
  2714. 3.6.8. Wie verhindere ich ein reordering der Spalten bei JTable?
  2715.        Autor: Linda Radecke
  2716. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2717. Das geht mit:
  2718.  
  2719. * table.getTableHeader().setReorderingAllowed(false);
  2720.  
  2721.  
  2722. 3.6.9. Wie verhindere ich ein Resizen der Spalten bei JTable?
  2723.        Autor: Linda Radecke
  2724. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2725. Das geht mit:
  2726.  
  2727. * table.getTableHeader().setResizingAllowed(false);
  2728.  
  2729.  
  2730. 3.6.10. Wie Σndere ich die Hintergrundfarbe von JScrollPane?
  2731.         Autor: Linda Radecke
  2732. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2733. Das geht mit:
  2734.  
  2735. * scrollpane.getViewport().setBackground(new Color(....));
  2736.  
  2737.  
  2738. 3.6.11. Wie kann ich ein JLabel dazu bringen, seinen Hintergrund
  2739.         zu fⁿllen?
  2740.         Autor: Gerhard Bloch
  2741. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2742. JLabel zeichnet (wie die meisten Swing-Komponenten) seinen Hintergrund
  2743. nicht, wenn es nicht "opaque" ist (obwohl dies unterschiedliche Dinge
  2744. sind).
  2745.  
  2746. Loesung:
  2747. Fuer *undurchsichtige* Hintergrundfarben funktioniert folgendes:
  2748.  
  2749. JLabel l = new JLabel("Text");
  2750. l.setOpaque(true);
  2751. l.setColor(Color.red);
  2752.  
  2753.  
  2754. Diese Loesung funktioniert auch fuer transparente Hintergrundfarben:
  2755.  
  2756. public class JLabelWithBackground extends JLabel {
  2757.     public JLabelWithBackground(String title) {
  2758.         super(title);
  2759.     }
  2760.  
  2761.     public void paintComponent(Graphics g) {
  2762.         if (!isOpaque()) {
  2763.             Rectangle vr = getVisibleRect();
  2764.             g.setColor(getBackground());
  2765.             g.fillRect(vr.x, vr.y, vr.width, vr.height);
  2766.         }
  2767.         super.paintComponent(g);
  2768.     }
  2769. }
  2770.  
  2771. JLabel l = new JLabelWithBackground("Text");
  2772. l.setBackground(new Color(255, 0, 0, 128));
  2773.  
  2774.  
  2775. 3.6.12. Warum reagiert meine GUI nicht, wΣhrend eine lΣngere 
  2776.         Berechnung ausgefⁿhrt wird?
  2777.         Autor: Tobias Vogele
  2778. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2779. Im Prinzip funktioniert das folgenderma▀en:
  2780. Es gibt bei Swing einen besonderen Thread: den Event Dispatch Thread
  2781. (EDT). Wenn immer Du ein Event von Deiner GUI bekommst, z.B. ein
  2782. ActionEvent, dann befindest Du Dich im Event Dispatch Thread (EDT). In
  2783. diesem werden aber nicht nur Events, die der Benutzer z.B. durch
  2784. Mausklicks verursacht hat, erzeugt, sondern in diesem Thread wird auch
  2785. die Anforderung fⁿr das Neuzeichnen verarbeitet
  2786.  
  2787. Das Problem ist nun: Wenn Du im EDT (z.B. bei der Behandlung eines
  2788. GUI-Events) eine lΣngere Berechnung oder was auch immer ausfⁿhrst, dann
  2789. kann in diesem Thread natⁿrlich so lange nichts anderes passieren, also
  2790. kann sich auch die GUI auch nicht mehr neu zeichnen, obwohl es
  2791. vielleicht n÷tig wΣre. Das bedeutet auch, da▀ ─nderungen, die wΣhrend
  2792. der Berechnung an der GUI vorgenommen werden, nicht sichtbar sind,
  2793. bevor die Berechnung nicht beendet ist, da erst dann die GUI neu
  2794. gezeichnet werden kann.
  2795.  
  2796. Die L÷sung ist daher: Du mu▀t Deine Berechnung in einem anderen Thread
  2797. ausfⁿhren.
  2798.  
  2799. Das weitere Problem dabei: Wenn diese Berechnung ─nderungen an der GUI
  2800. veranla▀t, dann mⁿssen diese wieder im EDT ausgefⁿhrt werden, da Swing
  2801. im allgemeinen nicht thread-safe ist.
  2802.  
  2803. Wie geht beides: 
  2804. Einen neuen Thread starten:
  2805.   new Thread(calculation, "CalculationThread").start();
  2806. Etwas im EDT ausfⁿhren:
  2807.   SwingUtilites.invokeLater(guiChanges);
  2808.  
  2809.  
  2810. Weitere Informationen dazu und alternative L÷sungsansΣtze:
  2811.  
  2812. 1) Artikel-Serie "Threads and Swing"
  2813. http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
  2814.  
  2815. 2) Foxtrott, ein Rahmenwerk um anders zu schreiben, was der 
  2816. Swing-Worker aus 1) kann:
  2817. http://foxtrot.sourceforge.net/
  2818.  
  2819. 3) Spin, eine weitere Threading-Bibliothek fⁿr Swing
  2820. http://spin.sourceforge.net/
  2821.  
  2822.  
  2823. Hier ein konkretes, lauffΣhiges Beispiel: 
  2824. WΣhrend einer lΣngeren Berechnung soll eine ProgressBar den 
  2825. Fortschritt anzeigen.
  2826.  
  2827. import java.awt.FlowLayout;
  2828. import java.awt.event.*;
  2829. import javax.swing.*;
  2830.  
  2831. public class Beispiel implements ActionListener{
  2832.  
  2833.         JProgressBar progressBar = new JProgressBar(0, 10);
  2834.  
  2835.         public void actionPerformed(ActionEvent e) {
  2836.                 Runnable calculation = new Runnable() {
  2837.                         public void run() {
  2838.                                 bigCalculation();
  2839.                         }
  2840.                 };
  2841.                 // Neuen Thread starten:
  2842.                 new Thread(calculation, "CalculationThread").start();
  2843.         }
  2844.  
  2845.         /**
  2846.          * Hier ist die gro▀e Berechnung, die gleichzeitig die 
  2847.          * ProgressBar updaten soll.
  2848.          */
  2849.         private void bigCalculation() {
  2850.                 for (int i = 0; i <= 10; i++) {
  2851.                         calculateNextStep();
  2852.                         setProgress(i);
  2853.                 }
  2854.         }
  2855.         
  2856.  
  2857.         void calculateNextStep() {
  2858.                 try {
  2859.                         Thread.sleep(500);
  2860.                 } catch (InterruptedException e) {
  2861.                 }
  2862.         }
  2863.  
  2864.  
  2865.         void setProgress(final int newProgress) {
  2866.                 // Wert der ProgressBar im EDT Σndern: 
  2867.                 SwingUtilities.invokeLater(new Runnable() {
  2868.                         public void run() {
  2869.                                 progressBar.setValue(newProgress);
  2870.                         }
  2871.                 });
  2872.         }
  2873.         
  2874.         public static void main(String[] args) {
  2875.                 Beispiel bsp = new Beispiel();
  2876.                 JButton button = new JButton("Rechne...");
  2877.                 button.addActionListener(bsp);
  2878.                 JFrame frame = new JFrame();
  2879.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  2880.                 frame.getContentPane().setLayout(new FlowLayout());
  2881.                 frame.getContentPane().add(button);
  2882.                 frame.getContentPane().add(bsp.progressBar);
  2883.                 frame.pack();
  2884.                 frame.setVisible(true);
  2885.         }
  2886. }
  2887.  
  2888.  
  2889. Es sei hier auch noch auf das Tutorial von Sun zur Verwendung von
  2890. JProgessBars hingewiesen, da dort anders vorgegangen wird als hier:
  2891. http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html
  2892.  
  2893. Dort wird die JProgressBar ⁿber einen Timer angesteuert und nicht ⁿber
  2894. einen expliziten Aufruf von setProgress. Allerdings war es ja hier
  2895. gerade die Absicht, zu zeigen, wie man aus einem extra Thread heraus
  2896. GUI-Methoden aufruft.
  2897.  
  2898.  
  2899. 3.7. [APPLET] - Frage zu Java-Applets und ihre Zusammenarbeit
  2900.                 mit Browsern.
  2901. --------------------------------------------------------------
  2902.  
  2903. 3.7.1. Welche JDK-Version sollte ich fⁿr Applets verwenden, die
  2904.        m÷glichst allgemein lauffΣhig sein sollen?
  2905.        Autor: Stefan Menzel
  2906. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2907. Am besten nicht ⁿber 1.1.8.
  2908.  
  2909.  
  2910. 3.7.2. Wie bekomme ich den Internet Explorer dazu, das Plugin
  2911.        anstelle der integrierten JVM zu benutzen.
  2912.        Autor: Stefan Menzel, Aljoscha Rittner, Joachim Sauer
  2913. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2914. Indem auf der aufrufenden Webseite nicht das <APPLET>, sondern das
  2915. <OBJECT>-Tag verwendet wird. Es gibt auf
  2916. <URL:http://java.sun.com/products/plugin/1.3/docs/html_converter.html>
  2917. einen automatischen Konverter einer Seite zur Benutzung des Plugins.
  2918.  
  2919. Mit 1.4 kann auch das APPLET-Tag zusammen mit dem Plugin verwendet
  2920. werden. Dazu findet man nΣhere Informationenen unter:
  2921.  
  2922. <URL:http://java.sun.com/j2se/1.4/docs/guide/plugin/developer_guide/
  2923. html_converter_more.html>
  2924.  
  2925. Anmerkung: Mit 1.4 kann auch das APPLET-Tag zusammen mit dem Plugin
  2926. verwendet werden. Aber alle, die fⁿr JDKs gr÷▀er 1.2 coden sollten
  2927. ohnehin OBJECT verwenden, da sie mit APPLET (auch mit den neuen Plugins)
  2928. auf Browser sto▀en k÷nnen, die zwar glauben es darstellen zu k÷nnen,
  2929. dann aber klΣglich scheitern. Wer fⁿr 1.1 programmiert sollte sich wohl
  2930. wirklich noch das APPLET-Tag ⁿberlegen.
  2931.  
  2932.  
  2933. 3.7.3. Was dⁿrfen unsignierte Applets nicht aus Sicherheitsgrⁿnden?
  2934.        Autor: Martin Erren
  2935. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2936. Applets wurden generell stark in ihren Rechten eingeschrΣnkt.
  2937. Die genauen EinschrΣnkungen sind von der Virtuellen Maschine,
  2938. also Browser / Plugin oder Appletviewer abhΣngig.
  2939.  
  2940. Einem signierten Applet kann man explizit mehr Rechte geben
  2941. als das normalerweise der Fall ist. Auch gibt es Unterschiede,
  2942. ob das Applet von remote oder vom Filesystem geladen wurde.
  2943.  
  2944. Ein von remote geladenes Applet darf in der Regel nicht:
  2945.  
  2946. * auf das lokale Filesystem zugreifen
  2947. * auf die (System-)Zwischenablage zugreifen
  2948. * Socketverbindungen zum lokalen Host aufbauen.
  2949. * Socketverbindungen zu dritt-Hosts aufbauen.
  2950. * System-properties Σndern/setzen
  2951. * System-properties lesen ausser:
  2952.   java.version, java.vendor,java.vendor.url, java.class.version
  2953.   os.name, os.arch, os.version,
  2954.   file.separator, path.separator, line.separator
  2955. * lokal Programme starten
  2956. * lokale Bibliotheken laden
  2957. * System.exit(int) aufrufen
  2958. * Fenster ohne Warnung ÷ffnen
  2959.  
  2960. Signieren heisst, das Applet mit einer verschlⁿsselten Unterschrift
  2961. (Signatur) zu versehen, um diesen mehr Rechte zuzuweisen.
  2962.  
  2963. Signieren bedarf einer "vertrauenswⁿrdigen" Person bzw. Institution,
  2964. unterschiedlich, je ob das Applet nur in einem Intra- oder im gesamten
  2965. Internet betrieben werden soll.
  2966.  
  2967. Der Prozess des Signieren-Lassens wurde leider noch zusΣtzlich
  2968. dadurch erschwert, dass man jede Signatur praktisch fⁿr jede
  2969. Browser-VM extra durchfⁿhren mus.
  2970.  
  2971. Genaueres siehe:
  2972.   <URL:http://java.sun.com/sfaq>
  2973. (Dort auch b÷se Testapplets.)
  2974.  
  2975. Zur Java-Security und Codesignierung allgemein siehe:
  2976.   <URL:http://www.securingjava.com/toc.html>
  2977.   <URL:http://home.iSTAR.ca/~neutron/java.html>
  2978.  
  2979. und spezieller:
  2980.  
  2981.   <URL:http://www.abim.net/jsw/index.htm>
  2982.   <URL:http://www.iw.uni-hannover.de/~ruemper/>
  2983.   <URL:http://www.suitable.com/Doc_CodeSigning.shtml>
  2984.   <URL:http://developer.netscape.com/docs/manuals/signedobj/signtool/
  2985.   index.htm> (umgebrochen)
  2986.   <URL:http://java.sun.com/products/plugin/1.2/docs/nsobjsigning.html>
  2987.   <URL:http://developer.java.sun.com/developer/onlineTraining/
  2988.   Programming/JDCBook/signed.html> (umgebrochen)
  2989.  
  2990.  
  2991. 3.8. [SERVER] - Frage zu Servlets und anderen Server-
  2992.                 Implementierungen in Java.
  2993. -----------------------------------------------------
  2994.  
  2995.  
  2996.  
  2997. 3.9. [NONCORE] - Fragen zu Klassen/Packages, die ⁿber den Kern der
  2998.                  Sprache  hinausgehen, also Java3D etc.
  2999. ------------------------------------------------------------------
  3000.  
  3001.  
  3002.  
  3003. 3.10. [OOP] - Frage bezⁿglich OOP-Konzepten und Patterns in Java.
  3004. ----------------------------------------------------------------
  3005.  
  3006. 3.10.1. Was bedeutet Vererbung im OO-Kontext?
  3007.         Autor: Markus Reitz
  3008. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3009. Vererbung ist in Java, und natⁿrlich auch in anderen Programmiersprachen,
  3010. nur eine M÷glichkeit, um das konkrete Problem in den Computer zu
  3011. ⁿbertragen. Das Prinzip der Vererbung ist dann anwendbar, wenn zwei
  3012. Objekte in einer ist-ein oder ist eine Art von Beziehung zueinander
  3013. stehen. Eine abgeleitete Klasse ist ein Subtyp der zugeh÷rigen
  3014. Oberklasse, besitzt also deren Eigenschaften (Daten & Methoden) und
  3015. erweitert diese bei Bedarf um neue. LKW und PKW sind zum Beispiel
  3016. Subtypen der Oberklasse Automobil, wobei beim LKW zum Beispiel die
  3017. maximal zulΣssige AnhΣngerlast oder die Achsenanzahl hinzukommt.
  3018.  
  3019. Wendet man das Prinzip der Vererbung an, so gilt das sogenannte
  3020. Liskov'sche Substitutionsprinzip:
  3021.  
  3022. Objekte der abgeleiteten Klasse k÷nnen stets an die Stelle von Objekten
  3023. der Oberklasse treten.
  3024.  
  3025.  
  3026. 3.10.2. Was bedeutet Aggregation im OO-Kontext?
  3027.         Autor: Markus Reitz
  3028. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3029. Das Prinzip der Aggregation besagt, da▀ ein Objekt aus mehreren Teilen
  3030. (=Objekten) besteht, die wiederrum aus Teilen bestehen k÷nnen usw.
  3031. Die Klasse Computer k÷nnte z.B. aus den Klassen Speicher, Festplatte
  3032. etc. bestehen. In einem Pseudo-Java-Code etwa so formuliert:
  3033.  
  3034. public class Computer {
  3035.     private Speicher rom;
  3036.     private Speicher ram;
  3037.     private Speicher festPlatte;
  3038.  
  3039.     (...)
  3040. }
  3041.  
  3042.  
  3043. 3.10.3. Was bedeutet Assoziation im OO-Kontext?
  3044.         Autor: Markus Reitz
  3045. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3046. Mit der Assoziation wird die Verbindung des Objektes zu einem oder
  3047. mehreren anderen Objekten beschrieben. Assoziationen k÷nnen kurzfristig
  3048. sein, zum Beispiel dann, wenn ein anderes Objekt an das aktuelle Objekt
  3049. als Parameter der Objektmethode ⁿbergeben wird. Sie k÷nnen aber auch
  3050. langfristig sein, wenn das Objekt Referenzen auf die assoziierten
  3051. Objekte speichert (Registrierung).
  3052.  
  3053.  
  3054. 3.10.4. Was bedeutet Benutzung im OO-Kontext?
  3055.         Autor: Markus Reitz
  3056. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3057. Das aktuelle Objekt benutzt eines oder mehrere andere Objekte um die
  3058. anstehende Aufgabe erfⁿllen zu k÷nnen. Das Objekt Backofen benutzt zum
  3059. Beispiel das Objekt Thermostat, um die Aufgabe backen zu erfⁿllen, damit
  3060. der Inhalt des Backofens nicht verkohlt.
  3061.  
  3062. Es mu▀ angemerkt werden, da▀ man hΣufig aus dem Programmcode keine
  3063. direkte Entscheidung treffen kann, ob Aggregation, Assoziation oder
  3064. Benutzung vorliegt. Diese drei Beziehungen sind prinzipiell
  3065. Designprinzipien, die in der spΣteren Implementierungsphase, zum
  3066. Beispiel in Java, in relativ Σhnliche oder sogar identische Konstrukte
  3067. umgesetzt werden. Es ist deshalb wichtig, da▀ man das jeweils zugrunde
  3068. gelegte Prinzip dokumentiert, damit die Funktionsweise besser und
  3069. einfacher nachvollzogen werden kann.
  3070.  
  3071.  
  3072. 3.10.5. Worin liegen die Unterschiede zwischen abstrakten Klassen
  3073.         und Interfaces?
  3074.         Autor: Markus Reitz
  3075. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3076. Java fⁿgt dem schon von C++ her bekannten Konzept der abstrakten Klasse
  3077. noch ein weiteres, aus der Sprache Objective-C entliehenes Feature hinzu:
  3078. Interfaces. Ein Interface ist zuersteinmal nichts anderes als eine
  3079. Auflistung von Methoden. Eine Klasse implementiert ein Interface, wenn
  3080. sie alle in der Interface-Deklaration angegebenen Methoden besitzt.
  3081. Wird mindestens eine der Methoden des Interfaces nicht implementiert, so
  3082. wird die Klasse zu einer abstrakten Klasse. Mit dem Interface-Prinzip
  3083. lassen sich in Java einfach Benutzt-Beziehungen modellieren. Eine Klasse
  3084. benutzt eine andere Klasse in dem Sinn, da▀ es ganz spezielle Methoden
  3085. dieser Klasse verwendet, um seine eigene FunktionalitΣt zu realisieren -
  3086. auf Daten der Hilfsklasse wird ja wegen dem Prinzip der Datenkapselung
  3087. nicht direkt zugegriffen. Um ein Objekt zu benutzen, ist es nur wichtig,
  3088. da▀ dieses Objekt die gewⁿnschten Funktionen auch besitzt. Man definiert
  3089. sich daher ein Interface, welches die ben÷tigten Funktionen auflistet.
  3090. Alle Objekte, die diese Funktionen ben÷tigen, sprich, die dieses
  3091. Interface verlangen, k÷nnen nun all die Klassen verwenden, die dieses
  3092. Interface implementieren. Im Sinne eines guten Klassendesigns ist es
  3093. daher wichtig, solche Benutzt-Beziehungen zu lokalisieren, um die
  3094. Klassen flexibler zu machen und unn÷tigerweise angewendete Vererbung zu
  3095. eliminieren. Abstrakte Klassen sind im Gegensatz dazu Modellierungen
  3096. des Ist ein-Prinzips und unterscheiden sich in dieser Hinsicht von
  3097. Interfaces.
  3098.  
  3099.  
  3100. 3.10.6. Was ist eine anonyme innere Klasse?
  3101.         Autor: Markus Reitz
  3102. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3103. Eine anonyme innere Klasse trΣgt keinen Namen und wird vor allem bei der
  3104. GUI-Programmierung fⁿr Adapterklassen verwendet. Wird eine solche Klasse
  3105. in ein Class-File ⁿbersetzt, so werden alle anonymen Klassen, die in der
  3106. umgebenden Klasse definiert wurden, von Null beginnend durhnummeriert.
  3107.  
  3108.     Testklasse$0.class
  3109.  
  3110. ist also das Class-File der ersten in der Klasse  Testklasse
  3111. auftauchenden anonymen inneren Klasse.
  3112.  
  3113.  
  3114. 3.10.7. Was ist ein immutable Objekt?
  3115.         Autor: Gerhard Bloch
  3116. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3117. Ein immutable (unveraenderliches) Objekt ist ein Objekt, das nach seiner
  3118. Instanzierung nicht mehr veraendert werden kann. Bekannte Beispiele
  3119. hierfuer sind saemtliche Wrapper-Klassen (Integer, Boolean,... ) sowie
  3120. die Klasse String.
  3121.  
  3122. Dieses Design-Pattern bietet folgende Vorteile:
  3123. + Instanzen koennen gefahrlos mehrfach referenziert werden
  3124. + keine Synchronisation noetig
  3125. + sehr gut geeignet als Schluessel fuer HashMap
  3126.  
  3127. Immutable Objekte muessen folgende Forderungen erfuellen:
  3128. + alle Attribute sind final
  3129. + alle nicht selbst immutable Attribute sind zusaetzlich private
  3130. + kein Schreibzugriff auf Attribute moeglich
  3131. + direkter Lesezugriff ist nur auf selbst immutable Attribute erlaubt
  3132. + im Konstruktor uebergebene mutable Objekte muessen geklont(*) werden
  3133.  
  3134. (*) Klonen ist hier in der Bedeutung "tief genug kopieren" gemeint: Es
  3135. muessen rekursiv alle mutable Attribute kopiert werden. Dies hoert sich
  3136. komplizierter an, als es in der Praxis ist, da die verwendeten Objekte
  3137. i.d.R. nicht verschachtelt sind, reicht meist eine flache Kopie aus.
  3138.  
  3139.  
  3140. Beispiel:
  3141.  
  3142. public class MyImmutable {
  3143.     public  final int i;
  3144.     private final String s;
  3145.     private final int[] a;
  3146.     private final Point p;
  3147.  
  3148.     public MyImmutable(int i, String s, int[] a, Point p) {
  3149.         this.i = i;                  // primitiver Typ ist immutable
  3150.         this.s = s;                  // String ist immutable
  3151.         this.a = new int[a.length];  // Arrays sind mutable!
  3152.         System.arraycopy(a, 0, this.a, 0, a.length);
  3153.         this.p = new Point(p);       // Point ist mutable!
  3154.     }
  3155.  
  3156.     public String getS() {
  3157.         return s;
  3158.     }
  3159.  
  3160.     // Array ist mutable, also Klon zurueckgeben
  3161.     public int[] getA() {
  3162.         return (int[]) a.clone();
  3163.     }
  3164.  
  3165.     // alternativ: Elementzugriff, die int-Elemente sind immutable
  3166.     public int getAAt(int pos) {
  3167.         return a[pos];
  3168.     }
  3169.  
  3170.     // Point ist mutable, also Klon zurueckgeben
  3171.     public Point getP() {
  3172.         return new Point(p);
  3173.     }
  3174. }
  3175.  
  3176.  
  3177. Zusaetzlich ist folgendes zu beachten:
  3178. Subklassen von Immutables muessen selbst nicht immutable sein und
  3179. koennen im schlimmsten Fall sogar das Konzept unterlaufen!
  3180.  
  3181. Beispiel:
  3182.  
  3183. public class AntiImmutable extends MyImmutable {
  3184.     public String s;
  3185.  
  3186.     public AntiImmutable(int i, String s, int[] a, Point p) {
  3187.         super(i, "", a, p);
  3188.         this.s = s;
  3189.     }
  3190.  
  3191.     public String getS() {
  3192.         return s;
  3193.     }
  3194. }
  3195.  
  3196. MyImmutable mi = new AntiImmutable(0, "A", anIntArray, new Point(0, 0));
  3197. ((AntiImmutable)mi).s = "B";
  3198. System.out.println(mi.getS());
  3199.  
  3200. --> Ergibt "B"!!!
  3201.  
  3202. Daher ist es meist angebracht, Immutables final zu deklarieren! Zudem
  3203. sollte man Attribute, die zwar immutable, aber nicht final sind, wie
  3204. Mutables behandeln (also im Konstruktor bzw. bei der Rueckgabe klonen).
  3205.  
  3206.  
  3207. 3.11. [JDK] - Frage zu virtuelle Maschinen, alles ⁿber JDKs und deren
  3208.               Installation und Verwendung.
  3209. ---------------------------------------------------------------------
  3210.  
  3211. 3.11.1. Was ist ein Java Development Kit (JDK)
  3212.         Autor: Hubert Partl
  3213. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3214. Das JDK ist eine Software, die fⁿr die Erstellung, ▄bersetzung und
  3215. Ausfⁿhrung von Java-Programmen notwendig ist; enthΣlt unter anderem den
  3216. Java-Compiler, das Java Runtime Environment JRE und diverse
  3217. Hilfsprogramme. Der Name bedeutet ⁿbersetzt Java-Entwicklungs-Werkzeug.
  3218.  
  3219.  
  3220. 3.11.2. Was ist ein Java Runtime Environment (JRE)
  3221.         Autor: Hubert Partl
  3222. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3223. Das JRE ist eine Software, die fⁿr die Ausfⁿhrung von Java-Programmen
  3224. notwendig ist; enthΣlt unter anderem die Java Virtual Machine JVM und
  3225. die Klassenbibliothek. Der Name bedeutet ⁿbersetzt Java-Laufzeit-
  3226. Umgebung.
  3227.  
  3228.  
  3229. 3.11.3. Was ist eine Java Virtual Machine (JVM)
  3230.         Autor: Hubert Partl
  3231. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3232. Die JVM ist eine die Software, die notwendig ist, um ein Java-
  3233. BinΣrprogramm (Bytecode) auf einem Computer auszufⁿhren. Der Name
  3234. bedeutet virtuelle Java-Maschine und kommt daher, dass der Computer,
  3235. der direkt nur Windows- oder Macintosh- oder Unix-BinΣrprogramme
  3236. ausfⁿhren kann, mit Hilfe der JVM so wirkt, als ob er Java-Bytecode
  3237. ausfⁿhren k÷nnte, also als ob er eine Java-Maschine wΣre.
  3238.  
  3239.  
  3240. 3.11.4. Wie konfiguriere ich JDK1.3/1.4 unter Linux oder Unix?
  3241.         Autor: Martin Erren, Michael Paap
  3242. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3243. Frage:
  3244.  
  3245. Bei meinem Linux ist per default kaffe (jdk1.1.8) eingestellt, obwohl
  3246. ich das Sun jdk installiert habe. Wie kann ich 1.3 unter Linux benutzen?
  3247.  
  3248. Antwort:
  3249.  
  3250. Die default-Einstellungen sind gut fⁿr jene, die nur GNU-Lizenzen
  3251. akzeptieren, aber schlecht fⁿr solche, die ernsthaft in Java entwickln
  3252. oder anspruchsvolle Java-Programme benutzen wollen.
  3253.  
  3254. I. SuSE Linux
  3255.  
  3256. SuSE macht die Umstellung auf das aktuelle Sun-jdk wenigstens einfach.
  3257. Sie muss jedoch per Hand erfolgen.
  3258.  
  3259. Ein normaler Benutzer hat /usr/lib/java/bin im $PATH.
  3260. (Unter root braucht/soll Java nicht gestartet werden)
  3261. /usr/lib/java ist ein symbolic link auf /usr/lib/jdk1.1.8,
  3262. eine Variante vom jdk 1.1.8 namens kaffe.
  3263.  
  3264. Man vergewissere sich dessen mit
  3265.  
  3266. # file /usr/lib/java
  3267.  
  3268. Falls tatsΣchlich ein symbolic link, kann man diesen getrost
  3269. (unter root) mit
  3270.  
  3271. # rm /usr/lib/java
  3272.  
  3273. l÷schen und mit
  3274.  
  3275. # ln -s /usr/java/jdk1.3.1_01 /usr/lib/java
  3276.  
  3277. auf das Sun jdk neu verlinken. Weiterhin sollte man in /etc/rc.config
  3278. die Variable CREATE_JAVALINK auf "no" setzen, sonst setzt SuSEConfig den
  3279. Link wieder in den Urzustand, wenn es das nΣchste Mal
  3280. lΣuft.
  3281.  
  3282. Diese Angaben gelten fⁿr SuSE 7.3 und k÷nnen pro
  3283. Distributions-Version geringfⁿgig von der beschriebenen
  3284. Struktur abweichen.
  3285.  
  3286. (Falls Dir symbolic links, file, rm, $PATH nichts sagen,
  3287. solltest Du Dir eine kleine Einfⁿhrung in UN*X besorgen,
  3288. zum Beispiel [...])
  3289.  
  3290.  
  3291. II. Unix/Linux Allgemein
  3292.  
  3293. Da andere Linux Distributionen nicht so verbreitet sind wie SuSE,
  3294. k÷nnen hier kaum alle Originalkonfigurationen durchgegangen werden.
  3295.  
  3296. Bei allen UN*X Varianten kann man aber immer so analysieren:
  3297.  
  3298. * Mit "java -version" die installierte JRE ⁿberprⁿfen.
  3299. * Mit "type java" erkennen ob "java" ein alias, oder eine ausfⁿhrbare
  3300.   Datei ist, bzw. wo sie im Filesystem liegt.
  3301. * Mit "file .../java" erkennen, ob es sich um ein script oder eine
  3302.   binary handelt.
  3303.  
  3304. Und so zu einem installierten Sun-JDK umlenken ($JAVA_HOME sei das
  3305. installierte Sun JDK):
  3306.  
  3307. * Den $PATH Σndern, Eintrag auf $JAVA_HOME/bin *vor* der Original-
  3308.   Binary
  3309. * "alias" setzen (hat immer Vorrang).
  3310. * Etwaige links umbiegen wie oben beschrieben.
  3311.  
  3312. Die Variable $JAVA_HOME sollte man ebenfalls setzen, da einige
  3313. Programme so das installierte JDK finden (z.B. Tomcat).
  3314.  
  3315.  
  3316. 3.11.5. Wie installiere und konfiguriere ich das jdk unter
  3317.         Windows 9x/Me/NT/2000 richtig?
  3318.         Autor: Wolfgang Schirmer
  3319. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3320. Als Referenz-jdk nehmen wir das jdk1.3.1 !
  3321. Nach dem Download des jdk 1.3.1 wird die Installationsroutine ⁿber den
  3322. klick auf die jdk1_3_1-win.exe gestartet. Nach der Begrⁿssung und den
  3323. Auszug aus den Lizenzbedingungen erfolgt die Auswahl des Installations-
  3324. verzeichnisses. StandardmΣssig wird das Verzeichnis C:\jdk1.3.1
  3325. vorgeschlagen. Dies kann aber ⁿber Browse geΣndert werden. Nach der
  3326. Festlegung des Installationsumfanges werden die Dateien auf die
  3327. Festplatte kopiert.
  3328.  
  3329. Durch die Eingabe des Kommandos:
  3330.  
  3331. java -version
  3332.  
  3333. in der DOS-Box kann festgestellt werden welche Version auf dem System
  3334. installiert wurde. Fⁿr dieses Beispiel sollte folgende Nachricht als
  3335. Reaktion auf das Kommando erscheinen:
  3336.  
  3337.     java version "1.3.1"
  3338.  
  3339. Als nΣchstes sind die PATH-Einstellungen zu ⁿberprⁿfen. Hierbei
  3340. ist es wichtig zu wissen, dass die PATH-Anweisung die Pfade festlegt,
  3341. in denen das Betriebssystem nach Programmen sucht.
  3342.  
  3343. Unter Windows 9x/Me wird die Pfadeinstellung in der autoexec.bat
  3344. durchgefⁿhrt. Hier sollte die PATH-Zeile folgendermassen aussehen:
  3345.  
  3346.     PATH=C:\WINDOWS;C:\WINDOWS\COMMAND;C:\jdk1.3.1\bin
  3347.  
  3348. Nach dieser ─nderung in der autoexec.bat muss das System neu
  3349. gestartet werden, damit die ─nderungen auch wirksam werden.
  3350.  
  3351. Unter WindowsNT/2000 ist die Pfadeinstellung in der
  3352. Systemsteuerung|System|Umgebung innerhalb der Systemvariablen
  3353. vorzunehmen. Hier ist der Eintrag in der Variablen PATH durch die
  3354. Zuweisung:
  3355.  
  3356.     ;C:\jdk1.3.1\bin
  3357.  
  3358. zu ergΣnzen. Die ─nderungen werden erst in den nach der ─nderung
  3359. ge÷ffneten DOS-Box wirksam. Achtung! Um unter WinNT/2000 diese
  3360. Einstellungen vornehmen zu k÷nnen muss man die Administrator-
  3361. Berechtigung besitzen.
  3362.  
  3363.  
  3364. 3.12. [TOOLS] - Frage zu einem Java-Zusatz-Tool, zum Beispiel IDEs,
  3365.                 Build-Tools, Profiler, etc.
  3366. -------------------------------------------------------------------
  3367.  
  3368. 3.12.1. Welche IDE muss ich verwenden?
  3369.         Autor: Martin Erren
  3370. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3371. <URL:http://groups.google.com/groups?q=beste+%2B+IDE+%2B+Java
  3372. ++-emacs+-vi+-vim+-notepad+group%3Ade.comp.lang.java&hl=de&btnG
  3373. =Google-Suche>
  3374.  
  3375. BTW: Der Link muss aus den 3 Zeilen zusammengesetzt werden !
  3376.  
  3377. Bietet eigentlich jederzeit einen guten ▄berblick.
  3378.  
  3379.  
  3380. 3.12.2. Wie kann man eine Java-Anwendung in eine EXE-Datei umwandeln?
  3381.         Autor: Marco Schmidt
  3382. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3383. Ein nativer Compiler ist in der Lage, Quelltext oder Bytecode in eine
  3384. native Anwendung (statt wie ⁿblich bei Java in Bytecode, also
  3385. .class-Dateien) umzuwandeln, etwa eine EXE-Datei unter Windows.
  3386.  
  3387. Auf
  3388.  
  3389. <URL:http://www.geocities.com/marcoschmidt.geo/java-native-compilers.html
  3390. #products>
  3391.  
  3392. sind u. a. auch einige native Compiler und weiterfⁿhrende Links zum
  3393. Thema "native compilation" aufgelistet.
  3394.  
  3395. BTW: Der Link muss aus 2 Zeilen zusammengesetzt werden !
  3396.  
  3397. Bei der Verwendung gibt es allerdings ein paar Punkte zu beachten.
  3398.  
  3399. * Gute native Compiler sind recht teuer und somit nur im
  3400. professionellen Umfeld sinnvoll einsetzbar. Der freie native Compiler
  3401. gcj unterstⁿtzt z. B. nur Java 1.1, und auch das nur teilweise (kein
  3402. AWT etc.).
  3403.  
  3404. * Obwohl das vom nativen Compiler erzeugte Programm aus nativem Code
  3405. besteht, mu▀ oft trotzdem noch ein Java Runtime Environment
  3406. installiert werden, so da▀ der Vorteil der einfachen Verteilung des
  3407. Programms wegfΣllt - der Benutzer k÷nnte genauso gut direkt das JRE
  3408. installieren und die Bytecode-Version der Anwendung starten.
  3409.  
  3410. * Der gro▀e Geschwindigkeitsvorteil durch nativen Code existiert
  3411. heutzutage nicht mehr, da moderne JVMs durch Just-in-time-Compiler in
  3412. den meisten FΣllen sehr nah an nativen Code herankommen. In
  3413. EinzelfΣllen mag es aber durchaus Vorteile bei nativem Code geben.
  3414.  
  3415. * Da es native Compiler nicht fⁿr all diejenigen Plattformen gibt, fⁿr
  3416. die auch JREs existieren, schrΣnkt man die Anzahl potentieller Nutzer
  3417. ein, wenn man auf nativen Code besteht. Allerdings dⁿrften mit nativen
  3418. Compilern fⁿr Windows und ein paar der verbreiteteren Unix-Varianten
  3419. absolut gesehen der gr÷▀te Teil aller Computerbenutzer abgedeckt sein.
  3420.  
  3421. * Wer nativen Code verwendet, mu▀ eventuell mehrere Versionen des
  3422. Programms fⁿr verschiedene Plattformen pflegen. Durch die Verwendung
  3423. von Bytecode (.class-Dateien) hat man eine Version, die ⁿberall
  3424. ausgefⁿhrt werden kann ("write once, run anywhere").
  3425.  
  3426. Zum Schlu▀ noch ein paar Vorteile durch die Verwendung eines nativen
  3427. Compilers.
  3428.  
  3429. * Native Programme starten meist schneller - dies ist fⁿr lang
  3430. laufende Server-Anwendungen nicht so wichtig, fⁿr hΣufig aufgerufene
  3431. Kommandozeilenprogramme allerdings schon eher.
  3432.  
  3433. * Es ist schwerer, nativen Code als Bytecode zu dekompilieren (also
  3434. wieder den Quelltext zu erhalten). Wer also Reverse-engineering seines
  3435. Programms fⁿrchtet, hat bei Bytecode mehr Anla▀ zur Sorge.
  3436.  
  3437. * Einige native Compiler erm÷glichen es, da▀ gleichzeitig laufende
  3438. Instanzen der erzeugten Programme sich gewisse Ressourcen teilen und
  3439. so weniger Arbeitsspeicher verbrauchen. Aktuelle JVMs laufen stets
  3440. v÷llig unabhΣngig voneinander ab (dies wird sich vielleicht nach Java
  3441. 1.4 Σndern).  Man kann mit nativen Anwendungen also mehr Instanzen
  3442. eines Programms auf demselben System laufen lassen.
  3443.  
  3444. Native Compiler haben in einigen Nischen also durchaus
  3445. Daseinsberechtigung. Allerdings sollte, wer sich um einfache
  3446. Verteilung seines Programms Gedanken macht, eine der folgenden
  3447. M÷glichkeiten in Betracht ziehen:
  3448.  
  3449. * Suns Java Webstart <URL:http://java.sun.com/products/javawebstart/>
  3450.  
  3451. * Ausfⁿhrbare JAR-Dateien, die sich mit einem Doppelklick auf das
  3452. entsprechende Icon starten lassen
  3453. <URL:http://java.sun.com/products/jdk/1.2/docs/guide/extensions/
  3454. spec.html#executable>
  3455.  
  3456. * Einen Installer wie InstallAnywhere <URL:http://www.zerog.com/>,
  3457. JExpress <URL:http://www.denova.com/> oder eines der Produkte aus dem
  3458. entsprechenden Abschnitt des Open Directory:
  3459. <URL:http://dmoz.org/Computers/Programming/Languages/Java/
  3460. Development_Tools/Deployment/>
  3461.  
  3462.  
  3463. 3.13. [MATH] - Mathematik, Arithmetik, Gleitpunktzahlen, Funktionen.
  3464. --------------------------------------------------------------------
  3465.  
  3466. 3.13.1. Warum rechnet Java falsch?
  3467.         Autor: Markus Reitz
  3468. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3469. Problem:
  3470.  
  3471. public class Test {
  3472.     public static void main(String[] args) {
  3473.         float zahl = 0.0F;
  3474.         for (int i = 0; i <= 100; i++) {
  3475.             System.out.println(zahl);
  3476.             zahl += 0.1F;
  3477.         }
  3478.     }
  3479. }
  3480.  
  3481. LΣ▀t man obiges Programm laufen so ergibt sich folgende Ausgabe:
  3482.  
  3483.     0.0
  3484.     0.1
  3485.     0.2
  3486.     0.3
  3487.     0.4
  3488.     0.5
  3489.     0.6
  3490.     0.70000005
  3491.     0.8000001
  3492.     0.9000001
  3493.     ...
  3494.  
  3495. Scheinbar rechnet Java an einigen Stellen falsch und ist nicht fΣhig,
  3496. zu einer Zahl den Wert 0.1 korrekt zu addieren. Dies sieht jedoch nur
  3497. so aus und ist auch keineswegs typisch fⁿr die Programmiersprache Java,
  3498. sondern ein allgemeines Problem.
  3499.  
  3500.  
  3501. Zahlendarstellung im Computer:
  3502.  
  3503. Um dies zu verstehen, mu▀ man sich klar machen, da▀ ganze Zahlen intern
  3504. in Form von BinΣrzahlen und Flie▀kommazahlen mit Hilfe von BinΣrbrⁿchen
  3505. dargestellt werden. Nun kann der (nicht gerade seltene) Fall eintreten,
  3506. da▀ sich eine Zahl im Dezimalsystem zwar darstellen lΣ▀t, in
  3507. BinΣrdarstellung jedoch zu einem unendlichen, nicht abbrechenden, Bruch
  3508. wird. Fⁿr die Speicherung einer Zahl steht aber nur ein beschrΣnkter
  3509. Speicherplatz zur Verfⁿgung, d.h. die unendliche BinΣrdarstellung wird
  3510. nur bis zu einer gewissen Stelle gespeichert. Das Resultat sind
  3511. Ungenauigkeiten. Addiert man jetzt solche Zahlen (und 0.1 ist ein
  3512. Beispiel fⁿr so eine Zahl) mehrfach auf, so addieren sich die
  3513. unvermeidbaren Ungenauigkeiten immer mehr auf und fⁿhren zu dem obigen
  3514. Verhalten. Dies ist keineswegs charakteristisch fⁿr Java, sondern auch
  3515. in jeder anderen Sprache, die Flie▀kommazahlen verwendet,
  3516. reproduzierbar. Eine Abmilderung des Problems besteht in einer schlauen
  3517. Rundung von Zwischenergebnissen an geeigneten Stellen der Berechnung,
  3518. so da▀ Fehler kompensiert oder zumindest abgeschwΣcht werden.
  3519.  
  3520.  
  3521. 3.13.2. Wie runde ich eine Gleitkommazahl?
  3522.         Wie formatiere ich eine Gleitkommazahl?
  3523.         Autor: Peter Luschny; Datum: 2004-02-04
  3524. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3525. Runden und Formatieren von Gleitkommazahlen
  3526.  
  3527. ::: 1. Einfⁿhrung ::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3528.  
  3529. Die Dezimaldarstellung einer Zahl a notieren wir (die Schreibweise a_{i}
  3530. bedeutet dabei "a mit einem tiefgestellten Index i")
  3531.  
  3532.   a = ▒ a_n a_{n-1} ... a_0 , a_{-1} a_{-2} ... a{-k}
  3533.  
  3534. wobei die a_i Ziffern '0','1,','2',...,'9' sind und a_n ungleich 0. Die
  3535. rechts vom Vorzeichen stehenden Ziffern hei▀en die 'tragenden Stellen'
  3536. von a, die rechts vom Komma stehenden Ziffern 'Nachkommastellen' von a.
  3537. Jede Zahl a ungleich 0 kann eindeutig in der Form dargestellt werden
  3538. a = m * 10^q, wobei 1 <= |m| < 10 und q eine ganze Zahl ist.
  3539. Diese Darstellung nennen wir die Gleitkommadarstellung von a.
  3540.  
  3541. Beispiel: Die Dezimalzahl 123,45678 hat die Gleitkommadarstellung
  3542. 1,2345678 * 102. Will man auf 2 /Nachkommastellen/ runden, so m÷chte man
  3543. die Dezimaldarstellung 123,46 erhalten, will man auf 2 /tragende Stellen/
  3544. runden, so m÷chte man die Gleitkommadarstellung 1,2 * 102 erhalten.
  3545.  
  3546. Die Java-Dokumentation wΣhlt noch eine andere Umsetzung. Hier wird die
  3547. Zahl aus dem Beispiel als [12345678, 5] dargestellt und allgemein die
  3548. Notation [m,s] verwendet, wobei a = m*10^(-s). Hier geht man also von der
  3549. Anzahl der Nachkommastellen aus (deren Endlichkeit vorausgesetzt wird),
  3550. und es wird von rechts nach links abgezΣhlt (man beachte das Minus-
  3551. Zeichen des Exponenten). Wir haben also die 3 Darstellungen
  3552.         123,45678 = 1,2345678 * 102 = [12345678, 5]
  3553.  
  3554. In einem Computer sind natⁿrlich nur endlich viele Gleitkommazahlen
  3555. darstellbar. In der Mathematik gibt es aber unendlich viele. Will man also
  3556. das mathematische Rechnen auf einem Computer 'simulieren', muss man
  3557. stΣndig versuchen, trotz dieses Umstandes m÷glichst nahe an den 'wahren'
  3558. Werten zu bleiben. Dieses AuswΣhlen eines geeigneten Stellvertreters unter
  3559. den im Rechner darstellbaren Zahlen ist es, was man, allgemein gesprochen,
  3560. 'Runden' nennt, und diese Operation ist im Grunde vor und nach jeder
  3561. arithmetischen Operationen notwendig, wenn man sicherstellen will, dass
  3562. die Gesetze der Mathematik nicht verletzt werden. Die bekanntesten Arten
  3563. zum Runden sind: den 'oberen' Nachbarn, den 'unteren' Nachbarn oder die
  3564. 'nΣchstliegende' Zahl im System der darstellbaren Gleitkommazahlen
  3565. auszuwΣhlen.
  3566.  
  3567. Neben dem Runden einer Gleitkommazahl geh÷rt zu den Standardaufgaben
  3568. sie geeignet zu 'formatieren'. Hier entscheidet man ⁿber die graphische
  3569. Darstellung einer Ziffernfolge beim Anzeigen oder Ausdrucken. Beide
  3570. Operationen sind begrifflich unabhΣngig voneinander, werden aber manchmal
  3571. verwechselt - dies ist einer der Grⁿnden, warum wir sie hier gemeinsam
  3572. besprechen. Das Ergebnis einer Rundung ist ein 'double', das Ergebnis
  3573. einer Formatierung ein 'String'. Fⁿr beide Operationen stellt die
  3574. Java-Bibliothek Klassen zur Verfⁿgung.
  3575.  
  3576. Fⁿr das Rechnen und Runden: 'java.math.BigDecimal',
  3577. Fⁿr das Formatieren: 'java.text.DecimalFormat'.
  3578.  
  3579. Die folgenden VorschlΣge setzen eine Version des JDK >= 1.5 voraus.
  3580. Wie komplex die Dinge sind, zeigt, dass die Dokumentation von BigDecimal
  3581. in der Version 1.5 allein 41 Seiten, die von 'DecimalFormat' 22 Seiten
  3582. lang ist. Es wird daher dringend empfohlen, diese Dokumentation zu lesen.
  3583.  
  3584. ::: 2. Das  Runden  einer  Gleitkommazahl ::::::::::::::::::::::::::::::::
  3585.  
  3586. Eine wichtige Art, Gleitkommazahlen in Java in den Griff zu bekommen,
  3587. ist es, die Klasse BigDecimal zu verwenden. Dies bietet Vorteile gegenⁿber
  3588. dem direkten Arbeiten mit 'doubles': In den Feinheiten und SonderfΣllen
  3589. der Gleitkomma-Arithmetik sind viele Fu▀angeln versteckt, ihnen durch den
  3590. Gebrauch der Bibliotheksfunktionen aus dem Weg zu gehen, ist ein guter Rat
  3591. nicht nur fⁿr AnfΣnger. Folgende einfache Funktion zum Runden einer
  3592. Gleitkommazahl zeigt, wie man dabei vorgehen kann.
  3593.  
  3594. //////////////////////////////////////////////////////////////////////////
  3595. public static double round
  3596.              (double d, int scale, RoundingMode mode, FormatType type)
  3597. {
  3598.    if (Double.isNaN(d) || Double.isInfinite(d)) return d;
  3599.    scale = Math.max(scale,0);  // Verhindert negative scale-Werte
  3600.    BigDecimal bd = BigDecimal.valueOf(d);
  3601.    if(type == FormatType.exp) {
  3602.       BigDecimal bc = new BigDecimal(bd.unscaledValue(),bd.precision()-1);
  3603.       return ((bc.setScale(scale, mode)).
  3604.                scaleByPowerOfTen(bc.scale()-bd.scale())).doubleValue();
  3605.    }
  3606.    return (bd.setScale(scale, mode)).doubleValue();
  3607. }
  3608. //////////////////////////////////////////////////////////////////////////
  3609.  
  3610. Kurzbeschreibung der Funktion:
  3611. /**
  3612.  * @param  d der zu rundende Gleitkommawert.
  3613.  * @param  scale die Anzahl der Nachkommastellen, falls type = fix,
  3614.  *         die Anzahl der tragenden Stellen - 1,  falls type = exp.
  3615.  *         scale sollte >= 0 sein (negative Werte werden auf 0 gesetzt).
  3616.  * @param  mode die Rundungsart: einer der Rundungsarten von BigDecimal,
  3617.  *         seit 1.5 in java.math.RoundingMode.
  3618.  * @param  type ein Element von "enum FormatType {fix, exp}" gibt an,
  3619.  *         auf welche Stellen sich die Rundung beziehen soll.
  3620.  *         FormatType.exp ('Exponential') steht fⁿr tragende Stellen,
  3621.  *         FormatType.fix ('Fixkomma') steht fⁿr Nachkommastellen.
  3622.  * @return der gerundete Gleitkommawert.
  3623.  * <p>Anmerkung: Fⁿr die Werte <tt>double</tt> NaN und ±Infinity
  3624.  * liefert round den Eingabewert unverΣndert zurⁿck.
  3625.  */
  3626.  
  3627. Beispiel: d = -Math.exp(702); for (int scale = 0; scale < 6; scale++)
  3628. System.out.println(round(d,scale,RoundingMode.HALF_EVEN,FormatType.exp));
  3629.  
  3630. 0 -> -7.0E304
  3631. 1 -> -7.5E304
  3632. 2 -> -7.49E304
  3633. 3 -> -7.494E304
  3634. 4 -> -7.4942E304
  3635. 5 -> -7.49422E304
  3636.  
  3637. Beispiel: d = Math.PI*10000.0; for (int scale = 0; scale < 6; scale++)
  3638. System.out.println(round(d,scale,RoundingMode.HALF_EVEN,FormatType.fix));
  3639.  
  3640. 0 -> 31416.0
  3641. 1 -> 31415.9
  3642. 2 -> 31415.93
  3643. 3 -> 31415.927
  3644. 4 -> 31415.9265
  3645. 5 -> 31415.92654
  3646.  
  3647. Die Enumeration "enum FormatType {fix, exp};" muss dabei selber definiert
  3648. werden. Man beachte auch die Verwendung der Factory-Methode valueOf().
  3649. Diese Form ist in der Regel dem Konstruktor 'BigDecimal(double val)'
  3650. vorzuziehen. Man lese dazu die ErlΣuterungen in der Dokumentation
  3651. (Version >= 1.5) von BigDecimal. "This is generally the preferred way to
  3652. convert a float or double into a BigDecimal.." Ein einfaches Beispiel
  3653. veranschaulicht den Unterschied:
  3654.  
  3655. System.out.println(BigDecimal.valueOf(1.005));
  3656. System.out.println(new BigDecimal(1.005));
  3657.  
  3658. >>>>   1.005
  3659. >>>>   1.00499999999999989341858963598497211933135986328125
  3660.  
  3661.  
  3662. In Java-Versionen vor 1.5 lΣ▀t sich BigDecimal.valueOf(d) simulieren durch
  3663. new BigDecimal(Double.toString(d))). Der 'if'-Zweig der Funktion 'round'
  3664. ist allerdings in Σlteren Versionen nicht (so einfach) zu erhalten: Die
  3665. Funktionen precision() und scaleByPowerOfTen() sind erst ab 1.5 im API
  3666. enthalten und mⁿssten bei Σlteren Versionen 'nachgebaut' werden. Entweder
  3667. eine nette ▄bungsaufgabe oder ein guter Grund, auf eine Version >= 1.5
  3668. umzusteigen.
  3669.  
  3670. BigDecimal stellt 8 M÷glichkeiten zur Rundung zur Verfⁿgung. Will man auf
  3671. 2 Stellen im 'kaufmΣnnischen Sinn' runden, so wΣhle man HALF_UP.
  3672. Der IEEE-Standard sieht diese Rundung allerdings nicht als den Normalfall
  3673. an, und bei numerischen Rechnungen wΣhlt man besser HALF_EVEN.
  3674. Gebrauchsfertig in handliche Makros gepackt:
  3675.  
  3676. public static double roundUpFix2 (double d) {
  3677.     return round (d, 2, RoundingMode.HALF_UP, FormatType.fix);
  3678. }
  3679.  
  3680. public static double roundEvenExp2 (double d) {
  3681.    return round (d, 2, RoundingMode.HALF_EVEN, FormatType.exp);
  3682. }
  3683.  
  3684. ::: 3. Das  Formatieren  einer  Gleitkommazahl :::::::::::::::::::::::::::
  3685.  
  3686. Fⁿr das Formatieren ist 'java.text.DecimalFormat' das angebotene Werkzeug.
  3687. Eine kleine Utility-Funktion 'format' mit einer Σhnlichen Aufrufstruktur
  3688. wie die Funktion 'round', zeigt hier einen Ansatz:
  3689.  
  3690. //////////////////////////////////////////////////////////////////////////
  3691. public static String format (double d, int scale, FormatType type)
  3692. {
  3693.     if (Double.isNaN(d) || Double.isInfinite(d))
  3694.         return Double.toString(d);
  3695.  
  3696.     scale = Math.max(scale,0); // Verhindert negative scale-Werte
  3697.     DecimalFormat df = new DecimalFormat();
  3698.     df.setMaximumFractionDigits(scale);
  3699.     df.setMinimumFractionDigits(scale);
  3700.  
  3701.     if( type == FormatType.exp ) {
  3702.         StringBuilder sb = new StringBuilder("0E0");
  3703.         if(scale > 0) sb.append(".000000000000000000",0,scale+1);
  3704.         df.applyPattern(sb.toString());
  3705.     }
  3706.     else {
  3707.         df.setGroupingUsed(false);
  3708.         df.setMinimumIntegerDigits(1);
  3709.     }
  3710.     return df.format( d );
  3711. }
  3712. //////////////////////////////////////////////////////////////////////////
  3713.  
  3714.  Kurzbeschreibung der Funktion:
  3715.  /**
  3716.  * @param  d der zu formatierende Gleitkommawert.
  3717.  * @param  scale die Anzahl der Nachkommastellen, falls type = fix,
  3718.  *         die Anzahl der tragenden Stellen - 1,  falls type = exp.
  3719.  *         scale sollte >= 0 sein (negative Werte werden auf 0 gesetzt).
  3720.  * @param  type ein Element von "enum FormatType {fix, exp}".
  3721.  *         FormatType.exp fordert eine eine wissenschaftliche Exponential-
  3722.  *         darstellung an, FormatType.fix fordert ein Fixkommaformat an.
  3723.  * @return eine Zeichenkette, die den Gleitkommawert darstellt und
  3724.            entsprechend den gewⁿnschten Parametern formatiert ist.
  3725.  * <p>Anmerkung: Fⁿr die Werte <tt>double</tt> NaN und ±Infinity
  3726.  * liefert diese Methode {@link Double#toString} zurⁿck.
  3727.  */
  3728.  
  3729. Auch hier muss die Enumeration "enum FormatType {fix, exp};" selber
  3730. definiert werden. Man beachte bei den folgenden Beispielen die Verwendung
  3731. von ',' anstelle von '.' bei der Ausgabe. Wir bekommen also in der Tat
  3732. Gleitkommazahlen und nicht Gleitpunktzahlen geliefert, wie sich das auch
  3733. geh÷rt, wenn die 'lokalen Einstellungen' auf Deutschland gesetzt sind.
  3734. Wer arabische oder indischen Ziffern bevorzugt, kann auch dies erreichen -
  3735. zur Verwendung von 'Locales' im Zusammenhang mit DecimalFormat verweisen
  3736. wir auf die Dokumentation. Die beiden Beispiele von oben nehmen, mit den
  3737. Voreinstellungen der deutschen Locale, folgende Gestalt an:
  3738.  
  3739. Beispiel: d = -Math.exp(702); for (int scale = 0; scale < 6; scale++)
  3740. System.out.println(scale+" -> "+format(d, scale, FormatType.exp));
  3741.  
  3742. 0 -> -7E304
  3743. 1 -> -7,5E304
  3744. 2 -> -7,49E304
  3745. 3 -> -7,494E304
  3746. 4 -> -7,4942E304
  3747. 5 -> -7,49422E304
  3748.  
  3749. Beispiel: d = Math.PI*10000.0; for (int scale = 0; scale < 6; scale++)
  3750. System.out.println(scale+" -> "+format(d, scale, FormatType.fix));
  3751.  
  3752. 0 -> 31416
  3753. 1 -> 31415,9
  3754. 2 -> 31415,93
  3755. 3 -> 31415,927
  3756. 4 -> 31415,9265
  3757. 5 -> 31415,92654
  3758.  
  3759. Bequeme Makros machen die Funktion jetzt gebrauchsfertig:
  3760. public static String formatFix2 (double d) {
  3761.     return format (d, 2, FormatType.fix);
  3762. }
  3763. public static String formatExp2 (double d) {
  3764.     return format (d, 2, FormatType.exp);
  3765. }
  3766.  
  3767. In vielen Anwendungen sind die Anforderungen an die Formatierung jedoch
  3768. wesentlich komplexer, weil dabei auch der fⁿr die Anzeige zur Verfⁿgung
  3769. stehende Platz berⁿcksichtigt werden muss. Eine Basisklasse dafⁿr, die
  3770. sich auch fⁿr eigene Experimente eignet, kann man hier finden:
  3771. <URL:http://www.javajungle.de/OpenSource/DecimalFormat/>
  3772.  
  3773. ::: 4. Runden  plus  Formatieren :::::::::::::::::::::::::::::::::::::::::
  3774.  
  3775. Als letztes eine Warnung: DecimalFormat verwendet /intern/ auch eine
  3776. Rundung, und zwar - fest verdrahtet - RoundingMode.HALF_EVEN. Das ist
  3777. schwerlich etwas anderes als ein Design-Bug, denn damit wird die
  3778. Verwendung der 7 anderen Rundungsarten von BigDecimal in Verbindung mit
  3779. dieser Formatierungsklasse problematisch.
  3780.  
  3781. Insbesondere sollte jeder, der DecimalFormat verwendet, sich klar darⁿber
  3782. sein, dass hier nicht kaufmΣnnisch gerundet wird! Dazu noch ein Beispiel:
  3783.  
  3784. Das einfache dform2 = new java.text.DecimalFormat("0.00") beschert
  3785. folgende '▄berraschung' beim Ausdruck einer Rechnung:
  3786.  
  3787. dform2( 10.495 ) -> 10,50
  3788. dform2( 10.505 ) -> 10,50
  3789. dform2( 10.515 ) -> 10,52
  3790.  
  3791. Zum Glⁿck bei▀t sich die interne Rundung von DecimalFormat nicht mit einer
  3792. vorgeschalteten Aufrundung, sofern es nur um das Formatieren geht, so dass
  3793. sich dieses Problem so l÷sen lΣ▀t:
  3794.  
  3795. public static String formatFixUp2 (double d) {
  3796.     return formatFix2(roundUpFix2(d));
  3797. }
  3798.  
  3799. formatFixUp2( 10.495 ) -> 10,50
  3800. formatFixUp2( 10.505 ) -> 10,51
  3801. formatFixUp2( 11.515 ) -> 11,52
  3802.  
  3803. Aber dieses Beispiel ist in erster Linie zur Illustration des Gesagten
  3804. gedacht. Denn bei kaufmΣnnischen Rechnungen gilt es die Maxime von Paul
  3805. Ebermann zu befolgen: "Beim Rechnen mit Geld verwende man NIE 'double'."
  3806. Zu diesem Thema lese man auch den zweiten Link, der unten angegeben ist.
  3807.  
  3808. ::: 5. Zusammenfassung  ::::::::::::::::::::::::::::::::::::::::::::::::::
  3809.  
  3810.   ----------------------------------------------------
  3811.        RUNDEN              |       FORMATIEREN
  3812.   ----------------------------------------------------
  3813.                      d = PI*10000.0;
  3814.    Nachkomma-Stellen       |  Fixpunkt-Format
  3815.    roundUpFix2(d)          |  formatFix2(d)
  3816.    Wert: double 31415.93   |  Wert: String "31415,93"
  3817.   ----------------------------------------------------
  3818.                      d = -exp(702);
  3819.    Tragende Stellen        |  Exponential-Format
  3820.    roundEvenExp2(d)        |  formatExp2(d)
  3821.    Wert: double -7.49E304  |  Wert: String "-7,49E304"
  3822.   ----------------------------------------------------
  3823.  
  3824. In dieser Gegenⁿberstellung wurde der Einfachheit willen ein Spezialfall
  3825. gewΣhlt, fⁿr die allgemeine Darstellung gilt Analoges.
  3826.  
  3827. ::: 6. Links und Literatur :::::::::::::::::::::::::::::::::::::::::::::::
  3828.  
  3829. *** Zur Verwendung der API:
  3830. <URL:http://java.sun.com/docs/books/tutorial/i18n/format/
  3831. decimalFormat.html>
  3832. <URL:http://www.javaworld.com/javaworld/jw-06-2001/jw-0601-cents_p.html>
  3833. *** GrundsΣtzliches zur (dezimalen) Gleitkomma-Arithmetik:
  3834. <URL:http://www2.hursley.ibm.com/decimal/decimal.html>
  3835. <URL:http://www2.hursley.ibm.com/decimal/decifaq.html>
  3836.  
  3837.  
  3838. 3.13.3. Wie kann ich in Java Zufallszahlen im Bereich 0..n erzeugen?
  3839.         Autor: Markus Reitz, Uwe Gⁿnther
  3840. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3841. Zur Erzeugung von Zufallszahlen bietet Java das Random-Objekt. Bevor
  3842. Zufallszahlen erzeugt werden k÷nnen, mu▀ ein solches Objekt erzeugt
  3843. werden, wobei ein  Random-Seed  genannter Zahlenwert ⁿbergeben wird, der
  3844. Anteil an der Berechnung von Zufallszahlen hat. Generell mu▀ man sagen,
  3845. da▀ es sich bei auf dem Computer erzeugten Zufallszahlen um keine echten
  3846. zufΣlligen Zahlenfolgen handelt, der Begriff Pseudo-Zufallszahlen trifft
  3847. das Ganze besser. Grundlage dieser Zahlen sind Generator-Funktionen, die
  3848. eine mehr oder minder zufΣllig erscheinende Folge von Zahlen erzeugen.
  3849.  
  3850. Fⁿr die Berechnung der Zahlen spielt der Random-Seed (quasi der Samen fⁿr
  3851. die Berechnung) eine gro▀e Rolle. Wird dieser Random-Seed m÷glichst
  3852. zufΣllig gewΣhlt, so sind die resultieren-den Zahlenfolgen beinahe echte
  3853. Zufallszahlen. In der Praxis hat es sich als brauchbar erwiesen, als
  3854. Random-Seed die jeweils aktuelle Systemzeit zu benutzen, damit
  3855. gewΣhrleistet ist, da▀ sich der Seed m÷glichst hΣufig Σndert.
  3856.  
  3857. Damit erzeugt man ein Random-Objekt am Besten wie folgt:
  3858.  
  3859.     Random zufall = new Random(System.currentTimeMillis());
  3860.  
  3861. oder
  3862.  
  3863.     Random zufall = new Random();
  3864.  
  3865. Wobei der Default-Kostruktor intern auch nur
  3866.  
  3867.     this(System.currentTimeMillis());
  3868.  
  3869. aufruft, wie die Firma Sun in ihrer Online Dokumentation schreibt.
  3870.  
  3871. Mit Hilfe der Member-Funktion nextInt() wird die nΣchste erzeugte
  3872. Integerzahl geliefert. In einem Gro▀teil der FΣlle m÷chte man jedoch
  3873. nicht Integerzahlen haben, die auch negative Werte annehmen k÷nnen,
  3874. sondern Zahlen im Bereich von 0 bis n. Hier kommt eine Variation der
  3875. nextInt() Methode ins Spiel, deren Anwendung die folgende Zeile
  3876. demonstriert:
  3877.  
  3878.     zahl = zufall.nextInt(n+1);
  3879.  
  3880. Ist einem die Saat von Random nicht zufΣllig genug, dann sollte man die
  3881. Klasse SecureRandom aus dem Package java.security verwenden. Hier werden
  3882. unter anderem je nach Plattform Betriebsystem spezifische Mechanismen
  3883. gewΣhlt, wie zum Beispiel unter UNIX /dev/urandom.
  3884.  
  3885.  
  3886. 3.14. [MISC] - Alles, was nicht in eine der anderen Rubriken pa▀t.
  3887. ------------------------------------------------------------------
  3888.  
  3889. 3.14.1. Ich komme mit dem import-Statement nicht klar, was mache ich
  3890.         falsch?
  3891.         Autor: Markus Reitz
  3892. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3893. Problem:
  3894.  
  3895. In einem Programm kommen folgende beide import-Statements vor:
  3896.  
  3897.     import java.awt.*;
  3898.     import java.awt.event.*;
  3899.  
  3900. Warum reicht nicht das erste Statement aus, um die n÷tigen Klassen und
  3901. Interfaces zu importieren?
  3902.  
  3903. Intuitiv wⁿrde man sagen, da▀ mit Hilfe des  *  alle Klassen und
  3904. Interfaces importiert werden, die unterhalb des Pfades java.awt stehen,
  3905. doch leider ist dies nicht so. Mit import java.awt.*; werden nur alle
  3906. Klassen importiert, die im Verzeichnis java.awt stehen, nicht jedoch
  3907. Klassen, die noch tiefer verschachtelt abgespeichert sind. Deshalb ist
  3908. das zweite import-Statement n÷tig, welches alle Klassen in
  3909. java.awt.event importiert.
  3910.  
  3911.  
  3912. 3.14.2. Warum gibt es Probleme bei final Werten in Verbindung mit
  3913.         elementaren Typen?
  3914.         Autor: Markus Reitz, Paul Ebermann
  3915. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3916. Angenommen, eine Klasse A ist wie folgt definiert:
  3917.  
  3918. public class A {
  3919.     final static boolean test = true;
  3920. }
  3921.  
  3922. Aus irgendeinem Grund wird die Definition der Klasse A auf Folgendes
  3923. geΣndert:
  3924.  
  3925. public class A {
  3926.     final static boolean test = false;
  3927. }
  3928.  
  3929. Die Klasse A wird neu compiliert und eine neue Klassendatei erzeugt.
  3930. Alle anderen Klassen, die das in Klasse A definierte Feld verwenden,
  3931. mⁿ▀ten nun mit dem korrigierten Wert false arbeiten.
  3932. Probiert man dies in der Praxis aus, so stellt man fest, da▀ dies
  3933. nicht der Fall ist. Der Grund liegt in der Sprachdefinition der Sprache
  3934. Java. Ein primitiver (elementarer) Datentyp, der das Modifiziererpaar
  3935. final static trΣgt, wird vom Compiler als Konstante behandelt und kann
  3936. ⁿberall, wo er im Programm auftritt, vom Compiler direkt durch den Wert
  3937. ersetzt werden. Um also zu erreichen, da▀ sich die in der Klasse A
  3938. gemachte ─nderung auf alle sie benutzenden Klassen auswirkt, mⁿssen
  3939. alle betroffenen Klassen neu ⁿbersetzt werden. Dies gilt aber nur, wenn
  3940. der Wert tatsΣchlich mit einer Compile-Zeit-Konstante initialisiert wird.
  3941.  
  3942. Ein Ausweg aus diesem Dilemma stellt hier die Verwendung des
  3943. Typ sicheren enum (type safe enum) dar, siehe weiter unten.
  3944.  
  3945.  
  3946. Eine weitere Typ sichere Variante findet sich in folgendem Beispiel:
  3947.  
  3948. public class A {
  3949.     final static boolean test = new Boolean(true).booleanValue();
  3950. }
  3951.  
  3952. GeΣndert dann:
  3953.  
  3954. public class A {
  3955.     final static boolean test = new Boolean(false).booleanValue();
  3956. }
  3957.  
  3958.  
  3959. 3.14.3. Was bedeuten "$" im Namen von Class-Files?
  3960.         Autor: Markus Reitz
  3961. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3962. Das Dollarzeichen innerhalb eines Klassennamens taucht auf, wenn innere
  3963. Klassen, also Klassen, die innerhalb einer anderen Klasse definiert sind,
  3964. verwendet werden. Somit ist
  3965.  
  3966.     Testklasse$InnereKlasse.class
  3967.  
  3968. die Class-Datei der inneren Klasse "InnereKlasse", die innerhalb der
  3969. Klasse  Testklasse  definiert worden ist.
  3970.  
  3971.  
  3972. 3.14.4. Wie lassen sich Bilder im Dateiformat XYZ laden oder speichern?
  3973.         Autor: Marco Schmidt
  3974. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3975. Seit Java 1.0 lassen sich mit java.awt.Toolkit GIF- und JPEG-Dateien
  3976. laden, seit Version 1.3 auch PNG (genaugenommen nicht nur aus Dateien,
  3977. sondern von beliebigen URLs und sogar aus Byte-Arrays). Das Speichern
  3978. von Bildern in diesen oder anderen Formaten wird nicht unterstⁿtzt. Da
  3979. weder java.awt.Image noch java.awt.image.BufferedImage die
  3980. Schnittstelle Serializable implementieren, lassen sich auch die
  3981. eingebauten Routinen zum Objekt-I/O nicht verwenden.
  3982.  
  3983. Eine Notl÷sung stellt eventuell die Verwendung von PixelGrabber bzw.
  3984. MemoryImageSource aus java.awt.image dar. Mit ersterem lassen sich
  3985. Pixel als RGBA-int-Werte aus einem beliebigen java.awt.Image-Objekt
  3986. extrahieren, mit letzterem erzeugt man ein Image-Objekt aus solchen
  3987. "int-Pixeln". Lesen und Schreiben von int-Arrays unterstⁿtzen u. a.
  3988. DataIn/OutputStream bzw. ObjectIn/OutputStream. Dabei ist zu bedenken,
  3989. da▀ dieser Ansatz vier Bytes pro Pixel verbraucht. Eventuell fⁿhrt die
  3990. zusΣtzliche Verwendung von
  3991. java.util.zip.DeflaterOut/InflaterInputStream zu Einsparungen.
  3992.  
  3993. Fⁿr gΣngige Dateiformate sind zahlreiche externe L÷sungen verfⁿgbar,
  3994. sowohl frei als auch kommerziell, in stark unterschiedlicher QualitΣt.
  3995. Unter
  3996. <URL:http://www.geocities.com/marcoschmidt.geo/java-image-coding.html>
  3997. befindet sich eine Liste. Die Bibliothek JIMI
  3998. <URL:http://java.sun.com/products/jimi/> ist ein guter Einstiegspunkt,
  3999. sie ist (seit Sun sie aufgekauft hat) kostenlos erhΣltlich und deckt eine
  4000. gr÷▀ere Anzahl Formate ab. Das Package com.sun.image.codec.jpeg - zum
  4001. Laden und Speichern von Bildern im JPEG-Format - ist in neueren
  4002. Sun-JREs und JDKs enthalten, man kann sich jedoch nicht darauf
  4003. verlassen, es auch in anderen Java-Distributionen zu finden.
  4004.  
  4005. Bei Verwendung des LZW-Algorithmus' (z. B. in GIF bzw. TIFF/LZW) ist
  4006. darauf zu achten, da▀ sowohl kommerzielle als auch Freeware-Produkte
  4007. in bestimmten LΣndern (inkl. USA und Deutschland) eine Lizenz beim
  4008. Patentbesitzer Unisys erwerben mⁿssen (siehe auch
  4009. <URL:http://dmoz.org/Computers/Data_Formats/Graphics/2D/GIF/>. Als
  4010. Alternative zu GIF ist PNG gut geeignet, da es GIFs Einsatzgebiet -
  4011. mit Ausnahme von Animationen - abdeckt und in modernen Browsern
  4012. unterstⁿtzt wird.
  4013.  
  4014. Mit Java 1.4 wurde ein eigenstΣndiges Package zum Laden und Speichern
  4015. eingefⁿhrt: javax.imageio. Dieses unterstⁿtzt zunΣchst nur das Lesen
  4016. von GIF, JPEG und PNG sowie das Schreiben von JPEG und PNG. Allerdings
  4017. plant Suns JAI-Team (Java Advanced Imaging, eine Java-Bibliothek fⁿr
  4018. Bildverarbeitung), fast alle Codecs aus JAI zu portieren, so da▀ sie
  4019. der Spezifikation von javax.imageio folgen. Das schlie▀t BMP, PNM
  4020. (Portable Anymap) und TIFF ein. In Zukunft soll JAI fⁿr Codecs
  4021. komplett auf die ImageIO-API aufbauen. Eine Einfⁿhrung befindet sich
  4022. auf <URL:http://java.sun.com/j2se/1.4/docs/guide/imageio/> oder bei
  4023. installiertem JDK unterhalb des Installationsverzeichnisses in
  4024. /docs/guide/imageio/index.html.
  4025.  
  4026. Auf <URL:http://www.jalice.net/myJava.htm> finden sich zahlreiche
  4027. Code-Beispiele und weiterfⁿhrende Informationen zum Umgang mit
  4028. Bildern, Java2D und der neuen ImageIO-API.
  4029.  
  4030.  
  4031. 3.14.5. Was geht nicht mit Java?
  4032.         Autor: Martin Erren
  4033. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4034. Einige Features sind sehr systemnah und k÷nnen wegen der
  4035. PlattformunabhΣngigkeit von Java nicht direkt gel÷st werden.
  4036.  
  4037. Oft ist liegt dabei das eigentliche Problem eher im Ansatz,
  4038. weil zu plattformspezifisch gedacht wird, statt gΣngige
  4039. Java-Paradigmen umzusetzen. So sind z.B. Properties jederzeit
  4040. Environment Variablen vorzuziehen.
  4041.  
  4042. Ansonsten schafft ein entsprechendes System.exec(...) Abhilfe
  4043. oder ein Bibliotheksaufruf, z.B. ⁿber JNI (Java Native Interface).
  4044. Ein fⁿr jede Plattform einzeln zu l÷sendes Problem.
  4045.  
  4046. Einige Bibliotheken wie JavaComm sind bereits fⁿr die
  4047. verschiedensten Plattformen implementiert.
  4048.  
  4049. CPU:
  4050.  Daten wie Taktfrequenz auslesen.
  4051.  
  4052. Speicher:
  4053.  Gesamtgr÷sse ermitteln, direkt manipulieren.
  4054.  
  4055. Laufwerke:
  4056.  Genauen Laufwerkstyp erkennen (CDRom,...)
  4057.  CD auswerfen
  4058.  
  4059. Filesystem:
  4060.  Partitionsgr÷sse bestimmen.
  4061.  Linux: genauen file type feststellen (block/stream devices,...)
  4062.    einzelne Berechtigungen auslesen
  4063.  Windows: Verknⁿpfungen folgen
  4064.    Native L÷sung:
  4065.     <URL:http://www.tolstoy.com/samizdat/jconfig.html>
  4066.  
  4067. Textconsole:
  4068.  Bildschirm l÷schen
  4069.  cursor position setzen
  4070.  Farben
  4071.    Native L÷sung:
  4072.     <URL:http://www.bmsi.com/tuipeer/>
  4073.    Pure java (ⁿber ANSI):
  4074.     <URL:http://purl.org/NET/ePaul/#pps>
  4075.  
  4076. Desktop:
  4077.  Nicht reckeckige Fenster
  4078.    Native L÷sung:
  4079.     <URL:http://www.l2fprod.com/software/skinlf/>
  4080.  Tray Icon
  4081.    Native L÷sung beschrieben bei:
  4082.     <URL:http://www.nevaobject.com/_docs/_coroutine/coroutine.htm#example>
  4083.  Fenster immer im Vordergrund halten
  4084.    Native L÷sung:
  4085.     <URL:http://www.mysrc.net/lib/java/MySRC-AlwaysOnTop-090.zip>
  4086.  
  4087. Netzwerk, Schnittstellen:
  4088.  ICMP
  4089.  Serielle + Parralle Schnittstelle ansteuern
  4090.    Native L÷sung:
  4091.     <URL:http://java.sun.com/products/javacomm/>
  4092.  
  4093. Tastatur:
  4094.  SHIFT, CNTRL, ALT alleine gedrⁿckt
  4095.  Windows Taste
  4096.  Standardeingabe ungepuffert lesen (statt flush bei \n)
  4097.  
  4098. Maus:
  4099.  Scrollrad (m÷glich ab JDK 1.4)
  4100.    Native L÷sung <URL:http://www.codeproject.com/java/mousewheel.asp>
  4101.  
  4102. Betriebssystem:
  4103.  Environment-Variablen lesen(unm÷glich seit 1.2)/schreiben.
  4104.  System-Shutdown.
  4105.  Windows: Registry lesen/schreiben (eingeschr. m÷glich ab JDK 1.4)
  4106.   Native L÷sung: <URL:http://www.trustice.com/java/jnireg/>
  4107.  
  4108.  
  4109. 3.14.6. Wie kann ich in meinem Java-Programm ein HTML-Dokument
  4110.         anzeigen lassen?
  4111.         Author: Marco Schmidt
  4112. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4113. Es gibt zwei L÷sungsansΣtze, das Einbinden von Java-Code, der dies
  4114. leistet, oder das Aufrufen eines externen Programms (Browser).
  4115.  
  4116. * Man kann das Dokument selbst in einer GUI-Komponente anzeigen
  4117.   lassen. Das hat den Vorteil, da▀ man unabhΣngig von externen
  4118.   Programmen ist.
  4119.  
  4120.   In der Standardbibliothek gibt es seit Java 1.2 in der Hierarchie
  4121.   javax.swing.text.html entsprechenden Code. Der ist allerdings nur
  4122.   fⁿr Swing-OberflΣchen geeignet, nicht fⁿr AWT. Darⁿber hinaus wird
  4123.   nur HTML 3.2 unterstⁿtzt.
  4124.  
  4125. * Eine Mischl÷sung ist die Verwendung eines reinen Java-Browsers wie
  4126.   HotJava <URL:http://java.sun.com/products/hotjava/3.0/>. Dieser
  4127.   Browser k÷nnte - nach KlΣrung der rechtlichen Details - mit dem
  4128.   Programm ausgeliefert werden und mⁿ▀te ⁿberall dort funktionieren,
  4129.   wo auch die eigene Java-Applikation ausgefⁿhrt wird. HotJava
  4130.   unterstⁿtzt auch nur HTML 3.2, ben÷tigt aber nur das AWT und Java 1.1.
  4131.  
  4132. * Eine Σhnliche L÷sung ist der ebenfalls in reinem Java geschriebene
  4133.   kommerzielle ICEbrowser:
  4134.   <URL:http://www.icesoft.no/ps_browser_overview.html>.
  4135.  
  4136. * BrowserLauncher ist eine Java-Klasse (Freeware) zum Starten des
  4137.   Standard-Browsers: <URL:http://browserlauncher.sourceforge.net/>
  4138.  
  4139. * Ein JavaWorld-Artikel versucht ebenfalls, den Standardbrowser zu
  4140.   finden und zu starten: "Java Tip 66: Control browsers from your Java
  4141.   application"
  4142.   <URL:http://www.javaworld.com/javaworld/javatips/jw-javatip66.html>
  4143.  
  4144. * Die kommerzielle Bibliothek JConfig bietet ─hnliches, unter
  4145.    Verwendung von nativem Code:
  4146.   <URL:http://www.tolstoy.com/samizdat/jcdocs/overview.html#WBLaunch>
  4147.  
  4148.  
  4149. 3.14.7. Unter Windows werden in der Konsole (DOS-Eingabeaufforderung)
  4150.          die Umlaute falsch ausgegeben. Wie kann ich das korrigieren?
  4151.          Author: Peter Karp
  4152. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4153. Das Problem liegt in der verwendeten Codepage. StandardmΣ▀ig geht ein
  4154. Java-Programm von der Codepage Latin1 aus, wΣhrend in der Windows-Konsole
  4155. eine andere Codepage (hier meist CP850) verwendet wird.
  4156.  
  4157. Intern werden bei Java ZeichensΣtze in Unicode codiert. Zur Ausgabe muss
  4158. das Java-Programm die Unicode-Kodierung in die passende Kodierung der
  4159. aktuellen Codepage konvertieren, welche fⁿr ein Zeichen -- im Unterschied
  4160. zu Unicode -- nur ein Byte verwendet. Die Umlaute liegen bei verschiedenen
  4161. Kodierungen oft nicht an der gleichen Stelle.
  4162.  
  4163. Die aktive Codepage kann unter Windows 2000/XP mit dem Befehl
  4164.  
  4165.     chcp
  4166.  
  4167. bzw. unter Windowx 9x mit dem Befehl
  4168.  
  4169.     mode con:cp
  4170.  
  4171. angezeigt werden.
  4172.  
  4173. StandardmΣ▀ig ist bei einem deutschen Windows Codepage 850 (manchmal auch
  4174. 437) in der Konsole aktiv. In den "normalen" Windows-Programmen wird immer
  4175. der MS-ANSI-Zeichensatz (Codepage 1252) verwendet. MS-ANSI ist weitgehend
  4176. mit Latin1, welches z.B. unter Linux verwendet wird, identisch. Die
  4177. 7-Bit-ASCII-Zeichen und die deutschen Umlaute sind an den gleichen
  4178. Stellen.
  4179.  
  4180.  
  4181. Somit gibt es zwei grundlegend verschiedene L÷sungen:
  4182.  
  4183. 1) Man Σndert die verwendete Codepage in Windows auf Codepage 1252 oder
  4184. Latin1.
  4185.  
  4186. a) Die Unix-Umgebung "Cygwin" fⁿr Windows benutzt Latin1 als Codepage.
  4187. Cygwin findet man unter www.cygwin.com und stellt unter anderem die
  4188. ⁿblichen Unix-Tools und eine Shell zur Verfⁿgung.
  4189.  
  4190. b) Unter Windows 2000/XP kann mit dem Befehl chcp die aktive Codepage
  4191. gewechselt werden. Dies alleine stellt aber noch nicht die korrekte
  4192. Ausgabe der Umlaute sicher, da auch der verwendete Font die richtige
  4193. Kodierung verwenden muss.
  4194.  
  4195. Sinnvollerweise erstellt man sich eine Verknⁿpfung zu einem neuen
  4196. Konsolenfenster, dass Codepage 1252 und einen dazu passenden Font
  4197. verwendet, da man in den anderen Konsolenfenstern in der Regel
  4198. wahrscheinlich weiterhin Codepage 850/437 verwenden will, um zu den
  4199. DOS-Programmen kompatibel zu bleiben:
  4200.  
  4201. 1. neue Verkⁿpfung auf Desktop erstellen
  4202. 2. Speicherort angeben: %SystemRoot%\system32\cmd.exe /k chcp 1252
  4203. 3. Name angeben: Konsole1252
  4204. 4. fertigstellen
  4205. 5. Eigenschaften der Verknⁿpfung Σndern und als Schriftart
  4206.    "Lucida Console" definieren. Optional gibt man noch den Pfad zu dem
  4207.    Verzeichnis mit den Java-Programmen bei "Ausfⁿhren in:" an.
  4208. 6. fertig, das wars - wird der Shortcut nun fⁿr Java-Programme verwendet,
  4209.    gibts keine Probleme mehr mit Umlauten
  4210.  
  4211. Der Font "Lucida Console" ist ein TrueType-Font im OpenType-Format, der
  4212. die Unicode-Codierung unterstⁿtzt und daher die Zeichen fⁿr alle
  4213. verfⁿgbaren Codepages beinhaltet. Die sog. "Rasterschriftart" hingegen
  4214. liegt immer in der OEM-Kodierung vor. Dabei ist die OEM-Kodierung, die
  4215. Kodierung, die im jeweiligen Land fⁿr "DOS-Programme" ⁿblich ist. Fⁿr
  4216. Deutschland ist das Codepage 850, fⁿr Amerika Codepage 437 usw. Falls man
  4217. das Aussehen der "Lucida Console" nicht mag, kann man einen neuen Font
  4218. installieren, der das OEM-Flag gesetzt hat, aber trotz dieses Flags die
  4219. Kodierung fⁿr Codepage 1252 verwendet. Diesen Font New1252.FON, und eine
  4220. ErklΣrung wie dieser zu nutzen ist, findet sich auf der Homepage von
  4221. <URL:http://www.uwe-sieber.de>.
  4222.  
  4223.  
  4224. 2) Alternativ kann im Java-Programm selbst sichergestellt werden, dass die
  4225. aktive Codepage zur Ausgabe berⁿcksichtigt wird.
  4226.  
  4227. Erstelle eine neue Klasse fⁿr dein Tool-Paket und
  4228. rufe sie mit
  4229.  
  4230.         new KonsolenUmlaut();
  4231.  
  4232. auf, oder packe das folgende Code-Beispiel in die Klasse, die das
  4233. Problem betrifft.
  4234.  
  4235. Diese M÷glichkeit sollte aber nicht fest codiert werden, sondern optional
  4236. ⁿber ein Argument beim Start des Programmes mitgegeben werden k÷nnen. Eine
  4237. weitere M÷glichkeit wΣre die Ausgabe des Befehls 'mode con:cp' auszuwerten
  4238. und dann die Codepage entsprechend zu ⁿbergeben.
  4239.  
  4240. Code-Beispiel
  4241. =============
  4242.  
  4243. /**
  4244.  * Gibt die Umlaute unter Windows in Codepage 850 aus. Eingabe von
  4245.  * der Konsole oder Dateioperationen sind davon unberⁿhrt und haben
  4246.  * auch die Umlaute korrekt nach Latin1.
  4247.  */
  4248. package myToolsPackage;
  4249.  
  4250. import java.io.*;
  4251.  
  4252. public final class KonsolenUmlaut {
  4253.     public KonsolenUmlaut() {
  4254.         String sys = System.getProperty("os.name");
  4255.         if (sys.startsWith("Windows")) {
  4256.             try {
  4257.                 System.setOut( new PrintStream( new
  4258.                             FileOutputStream(FileDescriptor.out),
  4259.                             false, "cp850"));
  4260.                 System.setErr( new PrintStream( new
  4261.                             FileOutputStream(FileDescriptor.err),
  4262.                             true, "cp850"));
  4263.             } catch (IOException e) { e.printStackTrace(); }
  4264.         }
  4265.     }
  4266. }
  4267.  
  4268.  
  4269. 3.15. [ERROR] - Fehlermeldungen
  4270. -------------------------------
  4271.  
  4272. 3.15.1. Warum findet Java den Konstruktor nicht?
  4273.         Autor: Markus Reitz
  4274. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4275. Problem:
  4276.  
  4277. public class Test {
  4278.  
  4279.     private int a;
  4280.     private int b;
  4281.  
  4282.     public void Test (int a , int b) {
  4283.         this.a = a;
  4284.         this.b = b;
  4285.     }
  4286.  
  4287.     public static void main (String[] args) {
  4288.  
  4289.         //Und hier eine Fehlermeldung.
  4290.         Test myTest = new Test (12, 13);
  4291.     }
  4292. }
  4293.  
  4294. Versucht man die obige Klasse zu ⁿbersetzen, so meckert der Compiler
  4295. mit der Meldung  Wrong number of arguments in constructor ... .
  4296. Die L÷sung des Problems ist einfach: Konstruktoren besitzen keinen
  4297. Rⁿckgabetyp, auch nicht void. In obigem Beispiel hat man nΣmlich nicht
  4298. den Konstruktor fⁿr die Klasse Test definiert, sondern eine Funktion,
  4299. die den selben Namen wie die Klasse hat. Weiter unten versucht man nun,
  4300. den vermeintlich definierten Konstruktor aufzurufen und bekommt die
  4301. beschriebene Fehlermeldung.
  4302.  
  4303. L÷sung:
  4304.  
  4305. public class Test {
  4306.  
  4307.     private int a;
  4308.     private int b;
  4309.  
  4310.     public Test (int a , int b) {
  4311.         this.a = a;
  4312.         this.b = b;
  4313.     }
  4314.  
  4315.     public static void main (String[] args) {
  4316.  
  4317.         //Hier kommt jetzt keine Fehlermeldung mehr!
  4318.         Test myTest = new Test (12 , 13);
  4319.     }
  4320. }
  4321.  
  4322.  
  4323. 3.15.2. Warum bekomme ich eine "NoClassDefFoundError" Fehlermeldung
  4324.         beim Starten von java?
  4325.         Autor: Markus Reitz, Sascha Raabe
  4326. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4327. Der Grund ist einfach: Man mu▀ der Java-Laufzeitumgebung mitteilen, wo
  4328. sich die *.class-Dateien des Programms befinden, damit die Ausfⁿhrung
  4329. erfolgen kann. Dies erreicht man bei der SUN-Implementierung mit dem
  4330. Aufrufparameter -cp fⁿr Classpath oder man setzt die Umgebungsvariable
  4331. CLASSPATH auf das Verzeichnis, in dem sich die *.class-Dateien befinden.
  4332.  
  4333. Ausserdem muss beim Aufruf des Programms der vollstΣndige Klassenname
  4334. angegeben werden. Dieser besteht aus Packagenamen und Name der Java
  4335. Klasse.
  4336.  
  4337. Beispiel:
  4338. Die Java Klasse "MyApp" befindet sich im Package "de.foo.bar". Der
  4339. Aufruf der Klasse erfolgt somit ⁿber:
  4340.  
  4341. java de.foo.bar.MyApp
  4342.  
  4343. Dabei ist auf Gross- und Kleinschreibung zu achten.
  4344.  
  4345. 3.15.3. Warum bekomme ich eine "Couldn't read <Name>" Fehlermeldung  beim
  4346.         Kompilieren mit javac?
  4347.         Autor: Markus Reitz
  4348. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4349. In Java gilt die einfache Regel, da▀ der Name der Datei, in der die
  4350. Klasse gespeichert ist, identisch mit dem Klassennamen sein mu▀, wobei
  4351. auf die korrekte Gro▀- und Kleinschreibung zu achten ist.
  4352.  
  4353.  
  4354. 3.15.4. Warum bekomme ich eine "class <Name> must be defined in a file
  4355.         called <Name>" Fehlermeldung  beim Kompilieren von javac?
  4356.         Autor: Markus Reitz
  4357. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4358. Hier gilt analog das unter dem vorherigen Punkt angefⁿhrte. Eine Datei,
  4359. in der der Quelltext der Klasse gespeichert ist, mu▀ den selben Namen
  4360. besitzen wie die Klasse im Quelltext.
  4361.  
  4362.  
  4363. 3.15.5. Warum wird beim Zugriff auf ein korrekt initialisiertes Objekt-
  4364.         Array eine NullPointerException geworfen?
  4365.         Autor: Markus Reitz
  4366. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4367. Problem:
  4368.  
  4369. public class A {
  4370.     public String text;
  4371. }
  4372.  
  4373. public class Test {
  4374.     public static void main (String[] args) {
  4375.         A array = new A[10];
  4376.         for(int i = 0; i < 10; i++) {
  4377.             //wirft NullPointerException
  4378.             array[i].text = "Test";
  4379.         }
  4380.     }
  4381. }
  4382.  
  4383. Fⁿhrt man das Programm aus, so erhΣlt man die im Programmtext erwΣhnte
  4384. NullPointerException, obwohl doch alles eigentlich ganz in Ordnung
  4385. aussieht. Der Teufel steckt aber im Detail. Mit A array[] = new A[10]
  4386. wird eben nicht ein Array von zehn Objekten vom Typ A erzeugt, sondern
  4387. nur ein Array, welches zehn Referenzen auf Objekte vom Typ A enthΣlt,
  4388. die eigentlichen Objekte werden damit nicht erzeugt.
  4389.  
  4390.  
  4391. L÷sung:
  4392.  
  4393. public class A {
  4394.     public String text;
  4395. }
  4396.  
  4397. public class Test {
  4398.     public static void main (String[] args) {
  4399.         A array = new A[10];
  4400.         for(int i = 0; i < 10; i++) {
  4401.             array[i] = new A();
  4402.             //wirft keine NullPointerException mehr
  4403.             array[i].text = "Test";
  4404.         }
  4405.     }
  4406. }
  4407.  
  4408.  
  4409. 3.15.6. Warum bekomme ich eine NullPointerException, wenn ich
  4410.         versuche, auf Methoden oder Attribute von in einem Array
  4411.         gespeicherten Objekten zuzugreifen?
  4412.         Autor: Michael Paap
  4413. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4414. Vermutlich hast Du zwar den Array erzeugt, nicht jedoch die
  4415. Objekte. Dann sind die Fields Deines Array mit null
  4416. initialisiert, d.h. die Referenzen existieren zwar, nicht
  4417. jedoch die referenzierten Objekte.
  4418.  
  4419. Abhilfe:
  4420.  
  4421. Um z.B. einen Array von sechs Buttons zu erzeugen, geht man
  4422. so vor:
  4423.  
  4424. Button[] myButtons = new Button[6];
  4425.  
  4426. for (int i = 0; i < myButtons.length; i++) {
  4427.     myButtons[i] = new Button();
  4428. }
  4429.  
  4430.  
  4431. 3.15.7. Warum meckert der Compiler bei nicht initialisierten final
  4432.         Variablen
  4433.         Autor: Markus Reitz
  4434. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4435. Ab Java 1.1 ist folgender Code gⁿltig:
  4436.  
  4437. public class Test {
  4438.     final int i;
  4439.  
  4440.     public Test(int i) {
  4441.         //finale Variable this.i wird mit dem Wert
  4442.         //von i initialisiert.
  4443.         this.i = i;
  4444.     }
  4445.  
  4446.     public Test() {
  4447.         //Fehler die finale Variable this.i muss auch in diesem
  4448.         //Konstruktor initialisiert werden.
  4449.     }
  4450. }
  4451.  
  4452. Es ist also m÷glich, Variablen mit finalen Werten zu erzeugen, deren
  4453. finaler Wert beim ersten initialisieren der Variablen einmalig
  4454. festgelegt werden kann. Allerdings kann dies nur innerhalb eines
  4455. Konstruktors geschehen und es mu▀ auf jeden Fall eine Initialisierung
  4456. der Variablen erfolgen, denn ansonsten meldet der Compiler Fehler.
  4457.  
  4458.  
  4459. 3.15.8. Was hat die Compilerfehlermeldung "... is deprecated" zu
  4460.         bedeuten?
  4461.         Autor: Markus Reitz
  4462. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4463. Diese Meldung erhΣlt man normalerweise dann, wenn Σltere Java-Programme
  4464. mit einer neuen Version des Compilers ⁿbersetzt werden sollen. Die
  4465. Meldung ist nur eine Warnung, also kein richtiger Fehler, die
  4466. FunktionalitΣt des Programms wird nicht beeintrΣchtigt. Die Methode,
  4467. die bei der Meldung "... is deprecated" genannt wird, sollte aber nach
  4468. M÷glichkeit nicht mehr im Programm verwendet werden, da das Konzept der
  4469. Klasse verΣndert wurde und deshalb die Methode unter UmstΣnden in
  4470. neueren Versionen nicht mehr implementiert sein wird. Treten also solche
  4471. Meldungen beim Compilieren auf, so sollte man die entsprechenden
  4472. Methoden durch die empfohlenen Varianten ersetzen, damit gewΣhrleistet
  4473. ist, da▀ das Programm auch mit spΣteren Versionen von Java einwandfrei
  4474. ⁿbersetzt werden kann.
  4475.  
  4476.  
  4477. 3.16. [ClassLoader] - Alles ⁿber Classloader
  4478. --------------------------------------------
  4479.  
  4480. 3.16.1 Wie funktionieren Classloader?
  4481.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4482. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4483. Fⁿr das Laden von Klassendefinitionen sind in Java Exemplare der
  4484. Klasse java.lang.ClassLoader zustΣndig.[1] Jede Klasse ist assoziiert
  4485. mit dem Classloader (kurz: CL), ⁿber den sie geladen wurde und kann
  4486. ⁿber diesen im Zusammenhang mit ihrem voll qualifizierten Klassennamen
  4487. eindeutig identifiziert werden.
  4488.  
  4489. Klassen mit gleichem Namen aber unterschiedlichen CL gelten als
  4490. verschieden; Casts zwischen den beiden Klassen funktionieren nicht. Da
  4491. die Klasse ueblicherweise auch bei der equals()-Operation herangezogen
  4492. wird, werden auch Objekte mit gleicher Struktur und gleichen Membern,
  4493. deren Klassen gleiche Namen aber unterschiedliche CL haben, als
  4494. unterschiedlich betrachtet.
  4495.  
  4496. Die im System vorhandenen CL bilden eine baumartige Hierarchie, in der
  4497. Anfragen nach oben weitergereicht werden k÷nnen (und sollen), und die in
  4498. einem 'obersten' CL (dem sog. Bootstrap-CL) wurzelt. Der Ladevorgang
  4499. teilt sich ⁿblicherweise auf in folgende Schritte:
  4500.  
  4501. 1. Es wird eine Anfrage an den CL gestellt, entweder explizit ⁿber
  4502. ClassLoader#loadClass(), indirekt ⁿber Class#forName() oder implizit
  4503. durch Verwendung eines Klassennamens im Sourcecode. In den letzten
  4504. beiden FΣllen wird der CL der Klasse, auf der forName() aufgerufen
  4505. wird bzw. derjenigen, aus welcher der gerade ausgefⁿhrte Code stammt,
  4506. verwendet.
  4507.  
  4508. 2. Der CL ⁿberprⁿft, ob die Klasse bereits von ihm geladen wurde.
  4509. Falls ja, sollte er das entsprechende Klassenexemplar gecached
  4510. haben[2] - dieses wird zurⁿckgeliefert, fertig.
  4511.  
  4512. 3. Der CL delegiert die Anfrage zunΣchst an den ihm ⁿbergeordneten CL,
  4513. der wiederum bei Punkt 2 mit der Bearbeitung beginnt. Kann dieser ein
  4514. Klassenexemplar liefern, wird dieses zurⁿckgegeben - fertig.
  4515.  
  4516. 4. Der CL holt den Bytecode - je nach CL kann dieser aus
  4517. unterschiedlichen Quellen stammen: .class-datei, .jar-datei, URL,
  4518. programmatisch generiertes Byte-Array, usw.
  4519.  
  4520. 5. Der Bytecode wird per ClassLoader#defineClass() in ein Exemplar von
  4521. java.lang.Class umgewandelt.
  4522.  
  4523. 6. Gegebenenfalls werden referenzierte Klassen und Interfaces rekursiv
  4524. geladen ('resolving').
  4525.  
  4526. (Wohlgemerkt: 'Der' CL einer Klasse ist derjenige in der
  4527. Delegationskette, der sie tatsΣchlich geladen hat (Schritt 2 oder 5),
  4528. nicht unbedingt derjenige, auf dem ursprⁿnglich loadClass() aufgerufen
  4529. wurde.)
  4530.  
  4531. Diese Vorgehensreihenfolge ist zwar erwⁿnscht, kann aber teilweise
  4532. nicht erzwungen werden. Insbesondere der Vorrang der Delegation kann
  4533. in seltenen FΣllen ignoriert werden, so z.B. beim Webapp-CL von
  4534. Tomcat[9].
  4535.  
  4536. Bei Vergleichen von Klassen oder Objekten, beim Laden von Ressourcen
  4537. (s.u.), bei Singletons[7] und bei 'Typesafe Enumerations'[8] kann man
  4538. unter unerwarteten CL-Bedingungen schweren Schiffbruch erleiden.
  4539.  
  4540. NΣheres zum CL-Mechanismus findet man z.B. bei [4], [5] und [6].
  4541.  
  4542.  
  4543. 3.16.2 Warum macht der Classloader im Servlet-Container Probleme?
  4544.        Warum funktioniert das Einlesen von Ressourcen ueber den
  4545.        Classloader bei mir nicht?
  4546.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4547. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4548. ▄blicherweise muss man sich nicht besonders oft mit CL befassen.
  4549. Ausnahmen sind Probleme beim Laden von Ressourcen aus dem Classpath
  4550. (=> dclj-FAQ 3.3.6.) und das Schreiben von Bibliotheken oder Klassen,
  4551. die im Kontext CL-technisch komplizierterer Umgebungen wie J2EE- oder
  4552. Servlet-Containern zur Anwendung kommen k÷nnen oder sollen.
  4553.  
  4554. Es gibt mehrere M÷glichkeiten, direkt oder indirekt an unterschiedliche
  4555. CL zu geraten: ▄ber die Klasse, die den gerade ausgefⁿhrten Code enthΣlt,
  4556. ⁿber eine beliebige andere Klasse oder ⁿber
  4557. Thread.currentThread().getContextClassLoader(). ▄blicherweise will man
  4558. sich m÷glichst tief in der CL-Hierarchie einklinken.
  4559.  
  4560. In Servlet-Containern fΣhrt man meist recht gut mit dem Context-CL des
  4561. aktuellen Threads, da der Container sich drum kuemmert, dass dieser
  4562. passend gesetzt ist, ebenso im Beispielcode. Anderswo ist das eine recht
  4563. wacklige Angelegenheit, da dieser Context-CL praktisch beliebig gesetzt
  4564. und wieder neu gesetzt werden oder auch null sein kann.
  4565.  
  4566. Das Laden ⁿber eine bestimmte Klasse bringt hingegen Probleme, wenn
  4567. deren CL kein Blatt der CL-Hierarchie darstellt und es m÷glich ist,
  4568. dass dynamisch auf tieferliegende Elemente zurⁿckgegriffen werden soll.
  4569. Beispiel: Eine Klasse in einem shared- oder common-Verzeichnis eines
  4570. Servlet-Containers will zur Laufzeit eine Webapp-spezifische Klasse
  4571. laden.
  4572.  
  4573. Ein weiteres Problem mit dem Einlesen von Ressourcen ueber den CL ist,
  4574. dass man ggfs. die entsprechenden Security-Privilegien benoetigt. Diese
  4575. Einschraenkung ist bei Verwendung von Class#GetResource[AsStream]() nicht
  4576. gegeben.
  4577.  
  4578. Aufgrund der vielen sich ergebenden Fallstricke ist ein Einlesen von
  4579. Ressourcen ueber Class/Classloader in komplexeren Umgebungen nur sehr
  4580. bedingt zu empfehlen. Bei Problemen damit oder mit dem Laden von Klassen
  4581. ist es hilfreich, erst einmal die Struktur der CL-Hierarchie zu klaeren.
  4582.  
  4583.  
  4584. 3.16.3 Wie lade ich eine Klasse neu?
  4585.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4586. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4587. Im Wortsinn: Eigentlich gar nicht.
  4588.  
  4589. Von 'guten' CLs wird gefordert, dass sie auf Anfragen nach demselben
  4590. Klassennamen auch stets dasselbe Class-Exemplar liefern.[2] Wenn ein
  4591. CL sich nicht daran hΣlt, k÷nnte es im System zwei Klassen geben, die
  4592. per Definition identisch sind, aber eine ganz andere Struktur oder
  4593. zumindest unterschiedliche Methodendefinitionen haben - ein sicheres
  4594. Rezept fⁿr ─rger.
  4595.  
  4596. Daher gilt seit Java 1.2: Eine Klasse kann nur entladen werden, wenn
  4597. der zugeh÷rige CL nicht mehr reachable und damit reif fⁿr den GC
  4598. ist.[3] DemgemΣss k÷nnen Klassen, die durch den Bootstraploader
  4599. geladen wurden, ⁿberhaupt nicht entladen werden. Vorsicht ist im
  4600. Umgang mit Σlteren VMs geboten: In Java 1.0 gab es ⁿberhaupt kein
  4601. Class-Unloading; in Java 1.1 konnten Klassen geradezu beliebig
  4602. entladen werden, mit entsprechend verwirrenden Konsequenzen, z.B. bei
  4603. Verwendung des Singleton-Patterns.[7]
  4604.  
  4605. Wie erzeugt man nun trotz alldem den Effekt des 'Neuladens' von
  4606. Klassen? Man lΣdt die geΣnderte Klassendefinition ⁿber einen neuen CL.
  4607. Damit sind Exemplare der alten Klasse inkompatibel zu Exemplaren der
  4608. neuen Version. ▄blicherweise 'vergisst' man beim Neuladen den alten
  4609. CL, so dass Exemplare der alten Klasse (so sie nicht anderweitig
  4610. referenziert werden) fΣllig fⁿr den GC werden.
  4611.  
  4612. Um dieses Auswechseln der Klasse fⁿr den Rest der Anwendung
  4613. transparent zu halten, empfiehlt es sich, diese Klasse hinter einem
  4614. Interface zu verstecken. Das Interface ist dem ⁿbergeordneten CL
  4615. bekannt und Anfragen danach werden vom Reloading-CL an diesen
  4616. delegiert, so dass ⁿberall in der Anwendung dasselbe Interface bekannt
  4617. ist. Die 'Σnderbare' Klasse muss dieses Interface implementieren. Ihre
  4618. Definition wird dann ⁿber einen Reloading-CL geladen und ein Exemplar
  4619. erzeugt, das dem Rest der Applikation ausschliesslich als AusprΣgung
  4620. des Interface zur Verfⁿgung gestellt wird. Ein Beispiel dieses
  4621. Vorgehens findet sich in [4] und im Beispielcode.
  4622.  
  4623.  
  4624. 3.16.4 Wie baue ich einen Plugin-Mechanismus?
  4625.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4626. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4627. Unter einem Plugin-Mechanismus versteht man gemeinhin eine
  4628. M÷glichkeit, zur Compilezeit der Applikation noch unbekannte Klassen,
  4629. die ⁿblicherweise dasselbe Interface implementieren, zum
  4630. Applikationsstart (oder irgendwann sonst zur Laufzeit) zu laden. Die
  4631. Plugin-Klassen (oder entsprechende Jars/Unterverzeichnisse) liegen
  4632. hierbei oft in einem besonderen Plugin-Verzeichnis, oder die
  4633. Klassennamen und Positionen im Dateisystem werden der Applikation ⁿber
  4634. eine Konfigurationsdatei mitgeteilt.
  4635.  
  4636. Zum Applikationsstart werden die Klassen ⁿber einen eigenen CL (das
  4637. kann ein selbstgeschriebener CL oder schlicht ein URLClassLoader[10]
  4638. sein) geladen und dem Rest der Applikation als Exemplar des
  4639. ⁿbergeordneten Interfacetyps bekanntgemacht.
  4640.  
  4641. Beispiele fⁿr Plugin-Mechanismen findet man in IDEs, Servlet-Containern
  4642. und Webbrowsern. Beim Entwickeln eines Plugin-Frameworks oder eines
  4643. Plugins koennen einem schnell fiese CL-Probleme begegnen - [12] und [13]
  4644. aus dem Eclipse-Wiki liefern etwas Anschauungsmaterial.
  4645.  
  4646.  
  4647. 3.16.5 Gibt's dazu auch Beispielcode?
  4648.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4649. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4650. // $HOME/player/PluginPlayer.java
  4651. import java.io.*;
  4652. import java.net.*;
  4653.  
  4654. public class PluginPlayer {
  4655.   public static void main(String[] argv) {
  4656.     try {
  4657.       BufferedReader in =
  4658.           new BufferedReader(new InputStreamReader(System.in));
  4659.       // Plugin-Verzeichnis setzen
  4660.       final File plugindir = new File(argv[0]).getCanonicalFile();
  4661.       do {
  4662.         // Suche alle .class-Files im Plugin-Verzeichnis
  4663.         File[] pluginfiles = plugindir.listFiles(
  4664.             new FilenameFilter() {
  4665.               public boolean accept(File dir, String name) {
  4666.                 return plugindir.equals(dir)
  4667.                     && name.endsWith(".class")
  4668.                     && name.indexOf("Plugin") > -1;
  4669.               }
  4670.             }
  4671.         );
  4672.         // Erzeuge einen Loader fuer dieses Verzeichnis
  4673.         URLClassLoader loader =
  4674.             new URLClassLoader(new URL[]{plugindir.toURL()});
  4675.         // Iteriere ueber alle .class-Files...
  4676.         System.out.println("Running plugins from: " + plugindir.toURL());
  4677.         int numplugins = pluginfiles.length;
  4678.         for (int plugincnt = 0; plugincnt < numplugins; plugincnt++) {
  4679.           // ...extrahiere den Klassennamen...
  4680.           String filename = pluginfiles[plugincnt].getName();
  4681.           String pluginname =
  4682.               filename.substring(0, filename.lastIndexOf("."));
  4683.           System.out.println("Running plugin: " + pluginname);
  4684.           // ...lade die Klasse, erzeuge eine Instanz und caste...
  4685.           Plugin plugin =
  4686.               (Plugin) (loader.loadClass(pluginname).newInstance());
  4687.           // ...setze den Context-Loader des ausfuehrenden Threads...
  4688.           Thread.currentThread().setContextClassLoader(loader);
  4689.           // ...rufe die entsprechende Methode auf...
  4690.           plugin.doIt();
  4691.           // ...und setze den Context-Loader zurueck.
  4692.           ClassLoader parentloader = loader.getParent();
  4693.           Thread.currentThread().setContextClassLoader(parentloader);
  4694.         }
  4695.         System.out.println("'q'[RET] to quit, [RET] to continue");
  4696.       }
  4697.       while (!"q".equals(in.readLine()));
  4698.     }
  4699.     catch (Exception exc) {
  4700.       exc.printStackTrace();
  4701.     }
  4702.   }
  4703. }
  4704.  
  4705. // $HOME/player/Plugin.java
  4706. public interface Plugin {
  4707.   void doIt() throws Exception;
  4708. }
  4709.  
  4710. // $HOME/plugins/CLTestPlugin.java
  4711. public class CLTestPlugin implements Plugin {
  4712.   // Laedt Klassen auf unterschiedliche Arten
  4713.   public void doIt() throws ClassNotFoundException {
  4714.     ClassLoader contextcl =
  4715.         Thread.currentThread().getContextClassLoader();
  4716.     Class ac1 =
  4717.         contextcl.loadClass("AnotherClass");
  4718.     Class ac2 = Class.forName("AnotherClass");
  4719.     String firstresult = (ac1 == ac2 ? "fine" :"inconsistent");
  4720.     System.out.println("Check #1: " + firstresult);
  4721.  
  4722.     ac1 = contextcl.loadClass("Plugin");
  4723.     ac2 = AnotherClass.class.forName("Plugin");
  4724.     Class ac3 = Plugin.class;
  4725.     String secondresult =
  4726.         (ac1 == ac2 && ac1 == ac3 ? "fine" :"inconsistent");
  4727.     System.out.println("Check #2: " + secondresult);
  4728.   }
  4729. }
  4730.  
  4731. // $HOME/plugins/AnotherClass.java
  4732. public class AnotherClass {
  4733. }
  4734.  
  4735. // $HOME/plugins/CLResourcePlugin.java
  4736. import java.io.*;
  4737.  
  4738. public class CLResourcePlugin implements Plugin {
  4739.   // Laedt einen Text als Ressource und gibt ihn aus
  4740.   public void doIt() throws IOException {
  4741.     InputStream instream = getClass().getResourceAsStream("msg.txt");
  4742.     BufferedReader inreader =
  4743.         new BufferedReader(new InputStreamReader(instream));
  4744.     String curline = null;
  4745.     while ((curline = inreader.readLine()) != null) {
  4746.       System.out.println(curline);
  4747.     }
  4748.     inreader.close();
  4749.   }
  4750. }
  4751.  
  4752. // $HOME/plugins/msg.txt
  4753. Hello, world!
  4754.  
  4755. // $HOME/plugins/CLListPlugin.java
  4756. public class CLListPlugin implements Plugin {
  4757.   // Listet alle beteiligten CL
  4758.   public void doIt() {
  4759.     ClassLoader contextcl= Thread.currentThread().getContextClassLoader();
  4760.     System.out.println("Context CL: " + contextcl);
  4761.     ClassLoader curcl = getClass().getClassLoader();
  4762.     while (curcl != null) {
  4763.       System.out.println(curcl);
  4764.       curcl = curcl.getParent();
  4765.     }
  4766.   }
  4767. }
  4768.  
  4769.  
  4770. 3.16.6 ClassLoader Ressourcen zu 3.16.1 bis 3.16.5
  4771.        Autor: Ortwin Glⁿck, Ulf Jaehrig, Patrick Roemer, Jan Schulz
  4772. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4773. [1] java.lang.ClassLoader API-Doc
  4774. <URL:http://java.sun.com/j2se/1.4.1/docs/api/java/lang/ClassLoader.html>
  4775.  
  4776. [2] JLS 12.2
  4777. <URL:http://java.sun.com/docs/books/jls/second_edition/html/
  4778. execution.doc.html#44459>
  4779.  
  4780. [3] JLS 12.7
  4781. <URL:http://java.sun.com/docs/books/jls/second_edition/html/
  4782. execution.doc.html#74294>
  4783.  
  4784. [4] JavaWorld-Artikel Classloader Java 1.0 Style
  4785. <URL:http://www.javaworld.com/javaworld/jw-10-1996/jw-10-indepth.html>
  4786.  
  4787. [5] JavaWorld-Artikel Classloader Java 1.1 Style
  4788. <URL:http://www.javaworld.com/javaworld/jw-03-2000/jw-03-classload.html>
  4789.  
  4790. [6] Sun-Tutorial Classloader Java 1.1 Style
  4791. <URL:http://developer.java.sun.com/developer/onlineTraining/Security/
  4792. Fundamentals/magercises/ClassLoader/index.html>
  4793.  
  4794. [7] JavaWorld-Artikel Classloader und Singletons
  4795. <URL:http://www.javaworld.com/javatips/jw-javatip52_p.html>
  4796.  
  4797. [8] JavaWorld-Artikel Typesafe Enumerations
  4798. <URL:http://www.javaworld.com/javatips/jw-javatip122_p.html>
  4799.  
  4800. [9] Tomcat Classloader-Howto
  4801. <URL:http://jakarta.apache.org/tomcat/tomcat-4.1-doc/
  4802. class-loader-howto.html>
  4803.  
  4804. [10] java.net.URLClassLoader API-Doc
  4805. <URL:http://java.sun.com/j2se/1.4.1/docs/api/java/net/URLClassLoader.html>
  4806.  
  4807. [11] SPI-Kapitel im Jar-Doc
  4808. <URL:http://java.sun.com/j2se/1.4.1/docs/guide/jar/
  4809. jar.html#Service%20Provider>
  4810.  
  4811. [12] Eclipse-Wiki Plugin-Development
  4812. <URL:http://eclipsewiki.swiki.net/114>
  4813.  
  4814. [13] Eclipse-Wiki Classloader Tricks
  4815. <URL:http://eclipsewiki.swiki.net/123>
  4816.  
  4817.  
  4818.  
  4819. 4. Bⁿcher zum Thema Java
  4820. ========================
  4821.  
  4822. 4.1. Kann mir jemand gute Literatur zum Thema Java empfehlen?
  4823. -------------------------------------------------------------
  4824. <URL:http://www.dclj.de/links.html> bietet eine kleine ▄bersicht ⁿber
  4825. Bⁿcher, die zum freien Download zur Verfⁿgung stehen. Weiterhin bietet
  4826. die Seite <URL:http://www.accu.org/bookreviews> viele aufschlussreiche
  4827. Besprechungen von Java-Bⁿchern.
  4828.  
  4829. Hier nochmal in aller Kⁿrze:
  4830.  
  4831. * The Java Tutorial - <URL:http://java.sun.com/docs/books/tutorial/>
  4832. * Java ist auch eine Insel - <URL:http://www.java-tutor.com/>
  4833. * Go To Java 2 - <URL:http://www.javabuch.de/>
  4834. * Thinking in Java - <URL:http://www.mindview.net/Books/TIJ/>
  4835.  
  4836.  
  4837.  
  4838. In Buchform sind die folgenden Werke interessant:
  4839.  
  4840. * Go To Java 2 - Handbuch der Java-Programmierung
  4841.  
  4842.    Guido Krⁿger
  4843.    Addison-Wesley
  4844.    ISBN: 382731710X
  4845.    15. September 2000
  4846.    1224 Seiten
  4847.    <URL:http://www.javabuch.de/>
  4848.  
  4849.    - Eines der Standardwerke fⁿr angehende Javaprogrammierer und
  4850.      Kaffetrinker. Zumindest als Onlineversion sollte es sich jeder mal
  4851.      angeschaut haben, denn es bietet einen umfassenden und dennoch nicht
  4852.      zu sehr ins Detail gehenden ▄berblick ueber die verschiedenen
  4853.      Komponenten der Sprache Java.
  4854.  
  4855. * Java ist auch eine Insel - Programmieren fⁿr die Java 2-Plattform in
  4856.   der Version 1.4
  4857.  
  4858.    Christian Ullenboom
  4859.    Galileo Press
  4860.    ISBN: 3898421740
  4861.    Dezember 2001
  4862.    1239 Seiten
  4863.    <URL:http://www.java-tutor.com/javabuch/download.htm>
  4864.  
  4865. * Java. Programmierhandbuch und Referenz fⁿr die Java-2-Plattform
  4866.    - Einfⁿhrung und Kernpakete. Mit CD-ROM.
  4867.  
  4868.    Stefan Middendorf, Reiner Singer
  4869.    dpunkt-Verlag, Heidelberg
  4870.    ISBN 3920993829
  4871.    1999
  4872.    1256 Seiten
  4873.  
  4874.  
  4875. * Java2 Designmuster und Zertifizierungswissen
  4876.  
  4877.    Friedrich Esser
  4878.    Galileo Press
  4879.    ISBN 3934358667
  4880.    2001
  4881.    654 Seiten
  4882.  
  4883.  
  4884. * Einfⁿhrung in die objektorientierte Programmierung mit Java
  4885.  
  4886.    Ernst-Erich Doberkat,
  4887.    Stefan Di▀mann Oldenbourg
  4888.    ISBN 3486247867
  4889.    2000
  4890.    315 Seiten
  4891.  
  4892.  
  4893. * Java Gently
  4894.  
  4895.    Judy M. Bishop
  4896.    Addison-Wesley
  4897.    ISBN 0201342979
  4898.    1998
  4899.    508 Seiten
  4900.  
  4901.  
  4902. * Die Java2 Fibel
  4903.  
  4904.    Ralf Kⁿnel
  4905.    Addison-Welsey
  4906.    ISBN 3827314100
  4907.    1999
  4908.    442 Seiten
  4909.  
  4910.  
  4911. * Datenbanken und Java. JDBC, SQLJ und ODMG
  4912.  
  4913.    Gunter Saake, Kai-Uwe Sattler
  4914.    dpunkt-Verlag, Heidelberg
  4915.    2000
  4916.    ISBN: 3932588541
  4917.  
  4918.  
  4919. * Java Servlet Programming
  4920.  
  4921.    Jason Hunter, William Crawford
  4922.    O'Reilly
  4923.    ISBN 156592391X
  4924.    1988
  4925.    510 Seiten
  4926.  
  4927.  
  4928. * Komponenten in Java: Einsatz und Entwicklung von JavaBeans
  4929.    mit VisualAge for Java
  4930.  
  4931.    Claudia Piemont
  4932.    dpunkt-Verlag
  4933.    ISBN 3932588215
  4934.    1999
  4935.    347 Seiten
  4936.  
  4937.  
  4938. * Design mit Java. Bessere Applets und Anwendungen
  4939.  
  4940.    Peter Coad, Mark Mayfield
  4941.    Markt und Technik
  4942.    ISBN: 3827295866
  4943.    1999
  4944.    301 Seiten
  4945.  
  4946.  
  4947. englischsprachig, aber auch gut:
  4948.  
  4949. * Effective Java, Programming Language Guide
  4950.  
  4951.    Joshua Bloch
  4952.    The Java Series
  4953.    Addison-Wesley
  4954.    ISBN 0201310058
  4955.  
  4956.  
  4957. * Image Processing in Java
  4958.  
  4959.    Douglas A. Lyon
  4960.    Prentice Hall
  4961.    ISBN 0-13-97457707
  4962.    1999
  4963.    532 Seiten
  4964.  
  4965.  
  4966. 5. Themenverwandte Internet Ressourcen
  4967. ======================================
  4968.  
  4969. 5.1. WWW-Sites
  4970. --------------
  4971.  
  4972. Deutschsprachige:
  4973.  
  4974. Java:
  4975.   + Immer aktuelle archivierte Version dieser Text FAQ
  4976.     <URL:ftp://rtfm.mit.edu/pub/usenet-by-group/
  4977.     de.answers/de/comp-lang-java/faq>
  4978.  
  4979.   + HTML Version dieser FAQ von Uwe Plonus
  4980.     <URL:http://de.geocities.com/uweplonus/faq/>
  4981.  
  4982.   + deutsche Java-FAQ von Markus Reitz (de.comp.lang.java)
  4983.     <URL:http://www.dclj.de/>
  4984.     <URL:http://www.geocities.com/SiliconValley/Foothills/5270/>
  4985.  
  4986.   + Java-Einfuehrung von Hubert Partl (BOKU Wien)
  4987.     <URL:http://www.boku.ac.at/javaeinf/>
  4988.  
  4989.   + Go to Java 2 von Guido Krueger (Addison Wesley Verlag)
  4990.     <URL:http://www.javabuch.de/>
  4991.     <URL:http://www.gkrueger.com/>
  4992.  
  4993.   + Java ist auch eine Insel von Christian Ullenboom
  4994.     <URL:http://java-tutor.com/>
  4995.  
  4996.   + Java Dokumentation von Brit Schroeter und Johann Plank
  4997.     <URL:http://www.selfjava.de/>
  4998.  
  4999.   + Liste weiterer Links, zusammengestellt von Ralf Geschke (Uni Koeln)
  5000.     <URL:http://infosoc.uni-koeln.de/akademie/java/>
  5001.  
  5002.  
  5003. HTML, XHTML:
  5004.   <URL:http://www.teamone.de/selfhtml/>
  5005.   <URL:http://www.boku.ac.at/htmleinf/>
  5006.   <URL:http://art2.ph-freiburg.de/HTML-Tutor/>
  5007.   <URL:http://www.netandmore.de/faq/>
  5008.  
  5009. XML:
  5010.   <URL:http://www.mintert.com/xml/>
  5011.   <URL:http://www.boku.ac.at/htmleinf/xmlkurz.html>
  5012.  
  5013. WAP und WML:
  5014.   <URL:http://www.boku.ac.at/htmleinf/wein.html>
  5015.   <URL:http://allnetdevices.com/faq/>
  5016.  
  5017.  
  5018. Englischsprachige:
  5019.  
  5020. Java:
  5021.   + Java Online-Doku der Firma Sun
  5022.     <URL:http://java.sun.com/docs/>
  5023.  
  5024.   + Java Tutorial der Firma Sun
  5025.     <URL:http://java.sun.com/docs/books/tutorial/index.html>
  5026.  
  5027.   + Java FAQ von Eliotte Rusty Harold
  5028.     <URL:http://sunsite.unc.edu/javafaq/javafaq.html>
  5029.  
  5030.   + Java Programmers FAQ von Peter van der Linden
  5031.     <URL:http://www.afu.com/javafaq.html>
  5032.  
  5033.   + Java Glossary von Roedy Green
  5034.     <URL:http://mindprod.com/gloss.html>
  5035.  
  5036.   + Thinking in Java von Bruce Eckel
  5037.     <URL:http://www.BruceEckel.com/javabook.html>
  5038.  
  5039.   + Java Tutorial von Prof. Baldwin
  5040.     <URL:http://www.phrantic.com/scoop/toc.htm>
  5041.  
  5042.   + Swing FAQ von Linda Radecke
  5043.     <URL:http://www.jalice.net/textfaq.htm>
  5044.     <URL:http://www.jalice.net/tablefaq.htm>
  5045.     <URL:http://www.jalice.net/componentfaq.htm>
  5046.  
  5047.   + Tips zu Java von Marco Schmidt
  5048.     <URL:http://jiu.sourceforge.net/javatips.html>
  5049.  
  5050. HTML, XML, XHTML u.a.:
  5051.   <URL:http://www.w3.org/>
  5052.  
  5053. WAP, WML:
  5054.   <URL:http://www.wapforum.org/>
  5055.  
  5056.  
  5057. Anmerkung: Diese Liste ist meine subjektive Auswahl und stellt
  5058. keinen Anspruch auf Vollstaendigkeit oder Objektivitaet.
  5059.  
  5060.  
  5061. 5.2. Newsgroups
  5062. ---------------
  5063.  
  5064.   <news:comp.lang.java.3d>
  5065.   <news:comp.lang.java.advocacy>
  5066.   <news:comp.lang.java.beans>
  5067.   <news:comp.lang.java.corba>
  5068.   <news:comp.lang.java.databases>
  5069.   <news:comp.lang.java.gui>
  5070.   <news:comp.lang.java.help>
  5071.   <news:comp.lang.java.machine>
  5072.   <news:comp.lang.java.programmer>
  5073.   <news:comp.lang.java.security>
  5074.   <news:comp.lang.java.softwaretools>
  5075.  
  5076.  
  5077. 5.3. Mailinglisten
  5078. ------------------
  5079.  
  5080.   <mailto:java-linux@java.blackdown.org>
  5081.   <mailto:nbusers@netbeans.org>
  5082.  
  5083.  
  5084. 6. JavaScript Internet Ressourcen.
  5085. ==================================
  5086.  
  5087. 6.1 WWW-Sites
  5088.  
  5089.     <URL:http://www.teamone.de/selfhtml/>
  5090.     <URL:http://www.dcljs.de/>
  5091.  
  5092.  
  5093. 6.2. Newsgroups
  5094.  
  5095.   <news:de.comp.lang.javascript>
  5096.  
  5097.  
  5098. 7. Credits
  5099. ==========
  5100. Folgende Personen waren an der Erstellung der FAQ beteiligt:
  5101.  
  5102. Werner Baumann,
  5103. Gerhard Bloch,
  5104. Frank Buss,
  5105. Paul Ebermann,
  5106. Alexander Elsholz,
  5107. Martin Erren,
  5108. Uwe Gⁿnther,
  5109. Erwin Hoffmann,
  5110. Ingo R. Homann,
  5111. Ulf JΣhrig,
  5112. Christian Kaufhold,
  5113. Georg Lipitsch,
  5114. Peter Luschny,
  5115. Stephan Menzel,
  5116. Alexander Merkelbach,
  5117. Michael Paap,
  5118. Hubert Partl,
  5119. Achim Peters,
  5120. Uwe Plonus,
  5121. Sascha Raabe,
  5122. Markus Reitz,
  5123. Aljoscha Rittner,
  5124. Wolfram Rⁿhaak,
  5125. Joachim Sauer,
  5126. Wolfgang Schirmer,
  5127. Marco Schmidt,
  5128. Michael Schmidt,
  5129. Karsten Schulz,
  5130. Roger Schuster,
  5131. Jochen Theodorou,
  5132. Tobias Vogele,
  5133. Christian Wederhake
  5134.  
  5135. (in alphabetischer Reihenfolge).
  5136.  
  5137. Die Version 1.0 dieser FAQ baut auf den FAQs von Hubert Partl,
  5138. Markus Reitz und Michael Schmidt auf.
  5139.  
  5140. Kritik und VerbesserungsvorschlΣge an der FAQ bitte direkt an den
  5141. Autor oder in die Newsgroup mit dem Tag [FAQ] im Subject.
  5142.