![]() |
| Home > FAQ on different themes > de > comp-lang-java > |
FAQ der Newsgroup de.comp.lang.java Version 1.41 vom 14.05.2004 |
Section 6 of 6 - Prev - Next
All sections - 1 - 2 - 3 - 4 - 5 - 6
die den selben Namen wie die Klasse hat. Weiter unten versucht man nun,
den vermeintlich definierten Konstruktor aufzurufen und bekommt die
beschriebene Fehlermeldung.
Lösung:
public class Test {
private int a;
private int b;
public Test (int a , int b) {
this.a = a;
this.b = b;
}
public static void main (String[] args) {
//Hier kommt jetzt keine Fehlermeldung mehr!
Test myTest = new Test (12 , 13);
}
}
3.15.2. Warum bekomme ich eine "NoClassDefFoundError" Fehlermeldung
beim Starten von java?
Autor: Markus Reitz, Sascha Raabe
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Der Grund ist einfach: Man muß der Java-Laufzeitumgebung mitteilen, wo
sich die *.class-Dateien des Programms befinden, damit die Ausführung
erfolgen kann. Dies erreicht man bei der SUN-Implementierung mit dem
Aufrufparameter -cp für Classpath oder man setzt die Umgebungsvariable
CLASSPATH auf das Verzeichnis, in dem sich die *.class-Dateien befinden.
Ausserdem muss beim Aufruf des Programms der vollständige Klassenname
angegeben werden. Dieser besteht aus Packagenamen und Name der Java
Klasse.
Beispiel:
Die Java Klasse "MyApp" befindet sich im Package "de.foo.bar". Der
Aufruf der Klasse erfolgt somit über:
java de.foo.bar.MyApp
Dabei ist auf Gross- und Kleinschreibung zu achten.
3.15.3. Warum bekomme ich eine "Couldn't read " Fehlermeldung beim
Kompilieren mit javac?
Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In Java gilt die einfache Regel, daß der Name der Datei, in der die
Klasse gespeichert ist, identisch mit dem Klassennamen sein muß, wobei
auf die korrekte Groß- und Kleinschreibung zu achten ist.
3.15.4. Warum bekomme ich eine "class must be defined in a file
called " Fehlermeldung beim Kompilieren von javac?
Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hier gilt analog das unter dem vorherigen Punkt angeführte. Eine Datei,
in der der Quelltext der Klasse gespeichert ist, muß den selben Namen
besitzen wie die Klasse im Quelltext.
3.15.5. Warum wird beim Zugriff auf ein korrekt initialisiertes Objekt-
Array eine NullPointerException geworfen?
Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Problem:
public class A {
public String text;
}
public class Test {
public static void main (String[] args) {
A array = new A[10];
for(int i = 0; i < 10; i++) {
//wirft NullPointerException
array[i].text = "Test";
}
}
}
Führt man das Programm aus, so erhält man die im Programmtext erwähnte
NullPointerException, obwohl doch alles eigentlich ganz in Ordnung
aussieht. Der Teufel steckt aber im Detail. Mit A array[] = new A[10]
wird eben nicht ein Array von zehn Objekten vom Typ A erzeugt, sondern
nur ein Array, welches zehn Referenzen auf Objekte vom Typ A enthält,
die eigentlichen Objekte werden damit nicht erzeugt.
Lösung:
public class A {
public String text;
}
public class Test {
public static void main (String[] args) {
A array = new A[10];
for(int i = 0; i < 10; i++) {
array[i] = new A();
//wirft keine NullPointerException mehr
array[i].text = "Test";
}
}
}
3.15.6. Warum bekomme ich eine NullPointerException, wenn ich
versuche, auf Methoden oder Attribute von in einem Array
gespeicherten Objekten zuzugreifen?
Autor: Michael Paap
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vermutlich hast Du zwar den Array erzeugt, nicht jedoch die
Objekte. Dann sind die Fields Deines Array mit null
initialisiert, d.h. die Referenzen existieren zwar, nicht
jedoch die referenzierten Objekte.
Abhilfe:
Um z.B. einen Array von sechs Buttons zu erzeugen, geht man
so vor:
Button[] myButtons = new Button[6];
for (int i = 0; i < myButtons.length; i++) {
myButtons[i] = new Button();
}
3.15.7. Warum meckert der Compiler bei nicht initialisierten final
Variablen
Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ab Java 1.1 ist folgender Code gültig:
public class Test {
final int i;
public Test(int i) {
//finale Variable this.i wird mit dem Wert
//von i initialisiert.
this.i = i;
}
public Test() {
//Fehler die finale Variable this.i muss auch in diesem
//Konstruktor initialisiert werden.
}
}
Es ist also möglich, Variablen mit finalen Werten zu erzeugen, deren
finaler Wert beim ersten initialisieren der Variablen einmalig
festgelegt werden kann. Allerdings kann dies nur innerhalb eines
Konstruktors geschehen und es muß auf jeden Fall eine Initialisierung
der Variablen erfolgen, denn ansonsten meldet der Compiler Fehler.
3.15.8. Was hat die Compilerfehlermeldung "... is deprecated" zu
bedeuten?
Autor: Markus Reitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Diese Meldung erhält man normalerweise dann, wenn ältere Java-Programme
mit einer neuen Version des Compilers übersetzt werden sollen. Die
Meldung ist nur eine Warnung, also kein richtiger Fehler, die
Funktionalität des Programms wird nicht beeinträchtigt. Die Methode,
die bei der Meldung "... is deprecated" genannt wird, sollte aber nach
Möglichkeit nicht mehr im Programm verwendet werden, da das Konzept der
Klasse verändert wurde und deshalb die Methode unter Umständen in
neueren Versionen nicht mehr implementiert sein wird. Treten also solche
Meldungen beim Compilieren auf, so sollte man die entsprechenden
Methoden durch die empfohlenen Varianten ersetzen, damit gewährleistet
ist, daß das Programm auch mit späteren Versionen von Java einwandfrei
übersetzt werden kann.
3.16. [ClassLoader] - Alles über Classloader
--------------------------------------------
3.16.1 Wie funktionieren Classloader?
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Für das Laden von Klassendefinitionen sind in Java Exemplare der
Klasse java.lang.ClassLoader zuständig.[1] Jede Klasse ist assoziiert
mit dem Classloader (kurz: CL), über den sie geladen wurde und kann
über diesen im Zusammenhang mit ihrem voll qualifizierten Klassennamen
eindeutig identifiziert werden.
Klassen mit gleichem Namen aber unterschiedlichen CL gelten als
verschieden; Casts zwischen den beiden Klassen funktionieren nicht. Da
die Klasse ueblicherweise auch bei der equals()-Operation herangezogen
wird, werden auch Objekte mit gleicher Struktur und gleichen Membern,
deren Klassen gleiche Namen aber unterschiedliche CL haben, als
unterschiedlich betrachtet.
Die im System vorhandenen CL bilden eine baumartige Hierarchie, in der
Anfragen nach oben weitergereicht werden können (und sollen), und die in
einem 'obersten' CL (dem sog. Bootstrap-CL) wurzelt. Der Ladevorgang
teilt sich üblicherweise auf in folgende Schritte:
1. Es wird eine Anfrage an den CL gestellt, entweder explizit über
ClassLoader#loadClass(), indirekt über Class#forName() oder implizit
durch Verwendung eines Klassennamens im Sourcecode. In den letzten
beiden Fällen wird der CL der Klasse, auf der forName() aufgerufen
wird bzw. derjenigen, aus welcher der gerade ausgeführte Code stammt,
verwendet.
2. Der CL überprüft, ob die Klasse bereits von ihm geladen wurde.
Falls ja, sollte er das entsprechende Klassenexemplar gecached
haben[2] - dieses wird zurückgeliefert, fertig.
3. Der CL delegiert die Anfrage zunächst an den ihm übergeordneten CL,
der wiederum bei Punkt 2 mit der Bearbeitung beginnt. Kann dieser ein
Klassenexemplar liefern, wird dieses zurückgegeben - fertig.
4. Der CL holt den Bytecode - je nach CL kann dieser aus
unterschiedlichen Quellen stammen: .class-datei, .jar-datei, URL,
programmatisch generiertes Byte-Array, usw.
5. Der Bytecode wird per ClassLoader#defineClass() in ein Exemplar von
java.lang.Class umgewandelt.
6. Gegebenenfalls werden referenzierte Klassen und Interfaces rekursiv
geladen ('resolving').
(Wohlgemerkt: 'Der' CL einer Klasse ist derjenige in der
Delegationskette, der sie tatsächlich geladen hat (Schritt 2 oder 5),
nicht unbedingt derjenige, auf dem ursprünglich loadClass() aufgerufen
wurde.)
Diese Vorgehensreihenfolge ist zwar erwünscht, kann aber teilweise
nicht erzwungen werden. Insbesondere der Vorrang der Delegation kann
in seltenen Fällen ignoriert werden, so z.B. beim Webapp-CL von
Tomcat[9].
Bei Vergleichen von Klassen oder Objekten, beim Laden von Ressourcen
(s.u.), bei Singletons[7] und bei 'Typesafe Enumerations'[8] kann man
unter unerwarteten CL-Bedingungen schweren Schiffbruch erleiden.
Näheres zum CL-Mechanismus findet man z.B. bei [4], [5] und [6].
3.16.2 Warum macht der Classloader im Servlet-Container Probleme?
Warum funktioniert das Einlesen von Ressourcen ueber den
Classloader bei mir nicht?
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Üblicherweise muss man sich nicht besonders oft mit CL befassen.
Ausnahmen sind Probleme beim Laden von Ressourcen aus dem Classpath
(=> dclj-FAQ 3.3.6.) und das Schreiben von Bibliotheken oder Klassen,
die im Kontext CL-technisch komplizierterer Umgebungen wie J2EE- oder
Servlet-Containern zur Anwendung kommen können oder sollen.
Es gibt mehrere Möglichkeiten, direkt oder indirekt an unterschiedliche
CL zu geraten: Über die Klasse, die den gerade ausgeführten Code enthält,
über eine beliebige andere Klasse oder über
Thread.currentThread().getContextClassLoader(). Üblicherweise will man
sich möglichst tief in der CL-Hierarchie einklinken.
In Servlet-Containern fährt man meist recht gut mit dem Context-CL des
aktuellen Threads, da der Container sich drum kuemmert, dass dieser
passend gesetzt ist, ebenso im Beispielcode. Anderswo ist das eine recht
wacklige Angelegenheit, da dieser Context-CL praktisch beliebig gesetzt
und wieder neu gesetzt werden oder auch null sein kann.
Das Laden über eine bestimmte Klasse bringt hingegen Probleme, wenn
deren CL kein Blatt der CL-Hierarchie darstellt und es möglich ist,
dass dynamisch auf tieferliegende Elemente zurückgegriffen werden soll.
Beispiel: Eine Klasse in einem shared- oder common-Verzeichnis eines
Servlet-Containers will zur Laufzeit eine Webapp-spezifische Klasse
laden.
Ein weiteres Problem mit dem Einlesen von Ressourcen ueber den CL ist,
dass man ggfs. die entsprechenden Security-Privilegien benoetigt. Diese
Einschraenkung ist bei Verwendung von Class#GetResource[AsStream]() nicht
gegeben.
Aufgrund der vielen sich ergebenden Fallstricke ist ein Einlesen von
Ressourcen ueber Class/Classloader in komplexeren Umgebungen nur sehr
bedingt zu empfehlen. Bei Problemen damit oder mit dem Laden von Klassen
ist es hilfreich, erst einmal die Struktur der CL-Hierarchie zu klaeren.
3.16.3 Wie lade ich eine Klasse neu?
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Im Wortsinn: Eigentlich gar nicht.
Von 'guten' CLs wird gefordert, dass sie auf Anfragen nach demselben
Klassennamen auch stets dasselbe Class-Exemplar liefern.[2] Wenn ein
CL sich nicht daran hält, könnte es im System zwei Klassen geben, die
per Definition identisch sind, aber eine ganz andere Struktur oder
zumindest unterschiedliche Methodendefinitionen haben - ein sicheres
Rezept für Ärger.
Daher gilt seit Java 1.2: Eine Klasse kann nur entladen werden, wenn
der zugehörige CL nicht mehr reachable und damit reif für den GC
ist.[3] Demgemäss können Klassen, die durch den Bootstraploader
geladen wurden, überhaupt nicht entladen werden. Vorsicht ist im
Umgang mit älteren VMs geboten: In Java 1.0 gab es überhaupt kein
Class-Unloading; in Java 1.1 konnten Klassen geradezu beliebig
entladen werden, mit entsprechend verwirrenden Konsequenzen, z.B. bei
Verwendung des Singleton-Patterns.[7]
Wie erzeugt man nun trotz alldem den Effekt des 'Neuladens' von
Klassen? Man lädt die geänderte Klassendefinition über einen neuen CL.
Damit sind Exemplare der alten Klasse inkompatibel zu Exemplaren der
neuen Version. Üblicherweise 'vergisst' man beim Neuladen den alten
CL, so dass Exemplare der alten Klasse (so sie nicht anderweitig
referenziert werden) fällig für den GC werden.
Um dieses Auswechseln der Klasse für den Rest der Anwendung
transparent zu halten, empfiehlt es sich, diese Klasse hinter einem
Interface zu verstecken. Das Interface ist dem übergeordneten CL
bekannt und Anfragen danach werden vom Reloading-CL an diesen
delegiert, so dass überall in der Anwendung dasselbe Interface bekannt
ist. Die 'änderbare' Klasse muss dieses Interface implementieren. Ihre
Definition wird dann über einen Reloading-CL geladen und ein Exemplar
erzeugt, das dem Rest der Applikation ausschliesslich als Ausprägung
des Interface zur Verfügung gestellt wird. Ein Beispiel dieses
Vorgehens findet sich in [4] und im Beispielcode.
3.16.4 Wie baue ich einen Plugin-Mechanismus?
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unter einem Plugin-Mechanismus versteht man gemeinhin eine
Möglichkeit, zur Compilezeit der Applikation noch unbekannte Klassen,
die üblicherweise dasselbe Interface implementieren, zum
Applikationsstart (oder irgendwann sonst zur Laufzeit) zu laden. Die
Plugin-Klassen (oder entsprechende Jars/Unterverzeichnisse) liegen
hierbei oft in einem besonderen Plugin-Verzeichnis, oder die
Klassennamen und Positionen im Dateisystem werden der Applikation über
eine Konfigurationsdatei mitgeteilt.
Zum Applikationsstart werden die Klassen über einen eigenen CL (das
kann ein selbstgeschriebener CL oder schlicht ein URLClassLoader[10]
sein) geladen und dem Rest der Applikation als Exemplar des
übergeordneten Interfacetyps bekanntgemacht.
Beispiele für Plugin-Mechanismen findet man in IDEs, Servlet-Containern
und Webbrowsern. Beim Entwickeln eines Plugin-Frameworks oder eines
Plugins koennen einem schnell fiese CL-Probleme begegnen - [12] und [13]
aus dem Eclipse-Wiki liefern etwas Anschauungsmaterial.
3.16.5 Gibt's dazu auch Beispielcode?
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// $HOME/player/PluginPlayer.java
import java.io.*;
import java.net.*;
public class PluginPlayer {
public static void main(String[] argv) {
try {
BufferedReader in =
new BufferedReader(new InputStreamReader(System.in));
// Plugin-Verzeichnis setzen
final File plugindir = new File(argv[0]).getCanonicalFile();
do {
// Suche alle .class-Files im Plugin-Verzeichnis
File[] pluginfiles = plugindir.listFiles(
new FilenameFilter() {
public boolean accept(File dir, String name) {
return plugindir.equals(dir)
&& name.endsWith(".class")
&& name.indexOf("Plugin") > -1;
}
}
);
// Erzeuge einen Loader fuer dieses Verzeichnis
URLClassLoader loader =
new URLClassLoader(new URL[]{plugindir.toURL()});
// Iteriere ueber alle .class-Files...
System.out.println("Running plugins from: " + plugindir.toURL());
int numplugins = pluginfiles.length;
for (int plugincnt = 0; plugincnt < numplugins; plugincnt++) {
// ...extrahiere den Klassennamen...
String filename = pluginfiles[plugincnt].getName();
String pluginname =
filename.substring(0, filename.lastIndexOf("."));
System.out.println("Running plugin: " + pluginname);
// ...lade die Klasse, erzeuge eine Instanz und caste...
Plugin plugin =
(Plugin) (loader.loadClass(pluginname).newInstance());
// ...setze den Context-Loader des ausfuehrenden Threads...
Thread.currentThread().setContextClassLoader(loader);
// ...rufe die entsprechende Methode auf...
plugin.doIt();
// ...und setze den Context-Loader zurueck.
ClassLoader parentloader = loader.getParent();
Thread.currentThread().setContextClassLoader(parentloader);
}
System.out.println("'q'[RET] to quit, [RET] to continue");
}
while (!"q".equals(in.readLine()));
}
catch (Exception exc) {
exc.printStackTrace();
}
}
}
// $HOME/player/Plugin.java
public interface Plugin {
void doIt() throws Exception;
}
// $HOME/plugins/CLTestPlugin.java
public class CLTestPlugin implements Plugin {
// Laedt Klassen auf unterschiedliche Arten
public void doIt() throws ClassNotFoundException {
ClassLoader contextcl =
Thread.currentThread().getContextClassLoader();
Class ac1 =
contextcl.loadClass("AnotherClass");
Class ac2 = Class.forName("AnotherClass");
String firstresult = (ac1 == ac2 ? "fine" :"inconsistent");
System.out.println("Check #1: " + firstresult);
ac1 = contextcl.loadClass("Plugin");
ac2 = AnotherClass.class.forName("Plugin");
Class ac3 = Plugin.class;
String secondresult =
(ac1 == ac2 && ac1 == ac3 ? "fine" :"inconsistent");
System.out.println("Check #2: " + secondresult);
}
}
// $HOME/plugins/AnotherClass.java
public class AnotherClass {
}
// $HOME/plugins/CLResourcePlugin.java
import java.io.*;
public class CLResourcePlugin implements Plugin {
// Laedt einen Text als Ressource und gibt ihn aus
public void doIt() throws IOException {
InputStream instream = getClass().getResourceAsStream("msg.txt");
BufferedReader inreader =
new BufferedReader(new InputStreamReader(instream));
String curline = null;
while ((curline = inreader.readLine()) != null) {
System.out.println(curline);
}
inreader.close();
}
}
// $HOME/plugins/msg.txt
Hello, world!
// $HOME/plugins/CLListPlugin.java
public class CLListPlugin implements Plugin {
// Listet alle beteiligten CL
public void doIt() {
ClassLoader contextcl= Thread.currentThread().getContextClassLoader();
System.out.println("Context CL: " + contextcl);
ClassLoader curcl = getClass().getClassLoader();
while (curcl != null) {
System.out.println(curcl);
curcl = curcl.getParent();
}
}
}
3.16.6 ClassLoader Ressourcen zu 3.16.1 bis 3.16.5
Autor: Ortwin Glück, Ulf Jaehrig, Patrick Roemer, Jan Schulz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[1] java.lang.ClassLoader API-Doc
[2] JLS 12.2
[3] JLS 12.7
[4] JavaWorld-Artikel Classloader Java 1.0 Style
[5] JavaWorld-Artikel Classloader Java 1.1 Style
[6] Sun-Tutorial Classloader Java 1.1 Style
[7] JavaWorld-Artikel Classloader und Singletons
[8] JavaWorld-Artikel Typesafe Enumerations
[9] Tomcat Classloader-Howto
[10] java.net.URLClassLoader API-Doc
[11] SPI-Kapitel im Jar-Doc
[12] Eclipse-Wiki Plugin-Development
[13] Eclipse-Wiki Classloader Tricks
4. Bücher zum Thema Java
========================
4.1. Kann mir jemand gute Literatur zum Thema Java empfehlen?
-------------------------------------------------------------
bietet eine kleine Übersicht über
Bücher, die zum freien Download zur Verfügung stehen. Weiterhin bietet
die Seite viele aufschlussreiche
Besprechungen von Java-Büchern.
Hier nochmal in aller Kürze:
* The Java Tutorial -
* Java ist auch eine Insel -
* Go To Java 2 -
* Thinking in Java -
In Buchform sind die folgenden Werke interessant:
* Go To Java 2 - Handbuch der Java-Programmierung
Guido Krüger
Addison-Wesley
ISBN: 382731710X
15. September 2000
1224 Seiten
- Eines der Standardwerke für angehende Javaprogrammierer und
Kaffetrinker. Zumindest als Onlineversion sollte es sich jeder mal
angeschaut haben, denn es bietet einen umfassenden und dennoch nicht
zu sehr ins Detail gehenden Überblick ueber die verschiedenen
Komponenten der Sprache Java.
* Java ist auch eine Insel - Programmieren für die Java 2-Plattform in
der Version 1.4
Christian Ullenboom
Galileo Press
ISBN: 3898421740
Dezember 2001
1239 Seiten
* Java. Programmierhandbuch und Referenz für die Java-2-Plattform
- Einführung und Kernpakete. Mit CD-ROM.
Stefan Middendorf, Reiner Singer
dpunkt-Verlag, Heidelberg
ISBN 3920993829
1999
1256 Seiten
* Java2 Designmuster und Zertifizierungswissen
Friedrich Esser
Galileo Press
ISBN 3934358667
2001
654 Seiten
* Einführung in die objektorientierte Programmierung mit Java
Ernst-Erich Doberkat,
Stefan Dißmann Oldenbourg
ISBN 3486247867
2000
315 Seiten
* Java Gently
Judy M. Bishop
Addison-Wesley
ISBN 0201342979
1998
508 Seiten
* Die Java2 Fibel
Ralf Künel
Addison-Welsey
ISBN 3827314100
1999
442 Seiten
* Datenbanken und Java. JDBC, SQLJ und ODMG
Gunter Saake, Kai-Uwe Sattler
dpunkt-Verlag, Heidelberg
2000
ISBN: 3932588541
* Java Servlet Programming
Jason Hunter, William Crawford
O'Reilly
ISBN 156592391X
1988
510 Seiten
* Komponenten in Java: Einsatz und Entwicklung von JavaBeans
mit VisualAge for Java
Claudia Piemont
dpunkt-Verlag
ISBN 3932588215
1999
347 Seiten
* Design mit Java. Bessere Applets und Anwendungen
Peter Coad, Mark Mayfield
Markt und Technik
ISBN: 3827295866
1999
301 Seiten
englischsprachig, aber auch gut:
* Effective Java, Programming Language Guide
Joshua Bloch
The Java Series
Addison-Wesley
ISBN 0201310058
* Image Processing in Java
Douglas A. Lyon
Prentice Hall
ISBN 0-13-97457707
1999
532 Seiten
5. Themenverwandte Internet Ressourcen
======================================
5.1. WWW-Sites
--------------
Deutschsprachige:
Java:
+ Immer aktuelle archivierte Version dieser Text FAQ
+ HTML Version dieser FAQ von Uwe Plonus
+ deutsche Java-FAQ von Markus Reitz (de.comp.lang.java)
+ Java-Einfuehrung von Hubert Partl (BOKU Wien)
+ Go to Java 2 von Guido Krueger (Addison Wesley Verlag)
+ Java ist auch eine Insel von Christian Ullenboom
+ Java Dokumentation von Brit Schroeter und Johann Plank
+ Liste weiterer Links, zusammengestellt von Ralf Geschke (Uni Koeln)
HTML, XHTML:
XML:
WAP und WML:
Englischsprachige:
Java:
+ Java Online-Doku der Firma Sun
+ Java Tutorial der Firma Sun
+ Java FAQ von Eliotte Rusty Harold
+ Java Programmers FAQ von Peter van der Linden
+ Java Glossary von Roedy Green
+ Thinking in Java von Bruce Eckel
+ Java Tutorial von Prof. Baldwin
+ Swing FAQ von Linda Radecke
+ Tips zu Java von Marco Schmidt
HTML, XML, XHTML u.a.:
WAP, WML:
Anmerkung: Diese Liste ist meine subjektive Auswahl und stellt
keinen Anspruch auf Vollstaendigkeit oder Objektivitaet.
5.2. Newsgroups
---------------
5.3. Mailinglisten
------------------
6. JavaScript Internet Ressourcen.
==================================
6.1 WWW-Sites
6.2. Newsgroups
7. Credits
==========
Folgende Personen waren an der Erstellung der FAQ beteiligt:
Werner Baumann,
Gerhard Bloch,
Frank Buss,
Paul Ebermann,
Alexander Elsholz,
Martin Erren,
Uwe Günther,
Erwin Hoffmann,
Ingo R. Homann,
Ulf Jährig,
Christian Kaufhold,
Georg Lipitsch,
Peter Luschny,
Stephan Menzel,
Alexander Merkelbach,
Michael Paap,
Hubert Partl,
Achim Peters,
Uwe Plonus,
Sascha Raabe,
Markus Reitz,
Aljoscha Rittner,
Wolfram Rühaak,
Joachim Sauer,
Wolfgang Schirmer,
Marco Schmidt,
Michael Schmidt,
Karsten Schulz,
Roger Schuster,
Jochen Theodorou,
Tobias Vogele,
Christian Wederhake
(in alphabetischer Reihenfolge).
Die Version 1.0 dieser FAQ baut auf den FAQs von Hubert Partl,
Markus Reitz und Michael Schmidt auf.
Kritik und Verbesserungsvorschläge an der FAQ bitte direkt an den
Autor oder in die Newsgroup mit dem Tag [FAQ] im Subject.
Section 6 of 6 - Prev - Next
All sections - 1 - 2 - 3 - 4 - 5 - 6
| Back to category comp-lang-java - Use Smart Search |
| Home - Smart Search - About the project - Feedback |
© allanswers.org | Terms of use