Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage |
<< | < | > | >> | API | Kapitel 1 - Was ist Java? |
Java wurde vollständig neu entworfen. Die Designer versuchten, die Syntax der Sprachen C und C++ soweit wie möglich nachzuahmen, verzichteten aber auf einen Großteil der komplexen und fehlerträchtigen Merkmale beider Sprachen. Das Ergebnis ihrer Bemühungen haben sie wie folgt zusammengefasst:
»Java soll eine einfache, objektorientierte, verteilte, interpretierte, robuste, sichere, architekturneutrale, portable, performante, nebenläufige, dynamische Programmiersprache sein.«
Der frühe Erfolg von Java hängt eng damit zusammen, dass ein wesentlicher Teil dieser Forderungen tatsächlich in einer für viele Programmierer akzeptablen Weise erfüllt wurde - obgleich wir am Ende dieses Kapitels auch einige kritische Anmerkungen dazu geben werden.
Java ist sowohl eine objektorientierte Programmiersprache in der Tradition von Smalltalk als auch eine klassische imperative Programmiersprache nach dem Vorbild von C. Im Detail unterscheidet sich Java aber recht deutlich von C++, das denselben Anspruch erhebt. Durch die Integration einer großen Anzahl anspruchsvoller Features wie Multithreading, strukturiertem Exceptionhandling oder eingebauten grafischen Fähigkeiten implementiert Java eine Reihe interessanter Neuerungen auf dem Gebiet der Programmiersprachen.
Zudem profitiert Java davon, dass viele der Features von C++ nicht realisiert wurden und die Sprache dadurch schlank und übersichtlich wurde. So gibt es beispielsweise keine expliziten Pointer, keine separaten Header-Dateien und keine Mehrfachvererbung. Wer allerdings glaubt, Java sei eine Programmiersprache, die nur das Allernötigste bietet, irrt. Tatsächlich ist Java eine elegante Sprache, die auch für größere Projekte und anspruchsvolle Aufgaben alle erforderlichen Voraussetzungen besitzt.
In Java gibt es die meisten elementaren Datentypen, die auch C besitzt. Arrays und Strings sind als Objekte implementiert und sowohl im Compiler als auch im Laufzeitsystem verankert. Methodenlose Strukturtypen wie struct oder union gibt es in Java nicht. Alle primitiven Datentypen sind vorzeichenbehaftet und in ihrer Größe exakt spezifiziert, unabhängig von der Zielplattform. Java besitzt einen eingebauten logischen Datentyp boolean.
Java bietet semidynamische Arrays, deren initiale Größe zur Laufzeit festgelegt werden kann. Arrays werden als Objekte angesehen, die wohldefinierte Eigenschaften haben. Mehrdimensionale Arrays werden wie in C dadurch realisiert, dass einfache Arrays ineinandergeschachtelt werden. Dabei können auch nichtrechteckige Arrays erzeugt werden. Alle Array-Zugriffe werden zur Laufzeit auf Einhaltung der Bereichsgrenzen geprüft.
Die Ausdrücke in Java entsprechen weitgehend denen von C und C++. Java besitzt eine if-Anweisung, eine while-, do- und for-Schleife und ein switch-Statement. Es gibt die von C bekannten break- und continue-Anweisungen in normaler und gelabelter Form. Letztere ermöglicht es, mehr als eine Schleifengrenze zu überspringen. Java besitzt kein goto-Statement (obgleich es sich um ein reserviertes Wort handelt). Variablendeklarationen werden wie in C++ als Anweisungen angesehen und können an beliebiger Stelle innerhalb des Codes auftauchen. Seit der Version 1.4 besitzt Java eine assert-Anweisung, die zur Laufzeit an- und abgeschaltet werden kann.
Java besitzt alle Eigenschaften moderner objektorientierter Programmiersprachen (»OOP-Sprachen«). Wie C++ erlaubt Java die Definition von Klassen, aus denen Objekte erzeugt werden können. Objekte werden dabei stets als Referenzdatentypen behandelt, die wie Variablen angelegt und verwendet werden können. Zur Initialisierung gibt es Konstruktoren und es kann eine optionale Finalizer-Methode definiert werden, die bei der Zerstörung des Objekts aufgerufen wird. Seit der Version 1.1 gibt es lokale Klassen, die innerhalb einer anderen Klasse definiert werden.
Alle Methodenaufrufe in Java sind dynamisch. Methoden können überladen werden, Operatoren allerdings nicht. Anders als in C++ ist das Late-Binding standardmäßig aktiviert, kann aber per Methode deaktiviert werden. Java erlaubt Einfach-, aber keine Mehrfachvererbung von Implementierungen. Mit Hilfe von Interfaces, also abstrakten Klassendefinitionen, die nur aus Methodensignaturen bzw. den Schnittstellen bestehen, ist jedoch eine restriktive Form der Mehrfachvererbung möglich. Java erlaubt die Definition abstrakter Basisklassen, die neben konkreten auch abstrakte Methoden enthalten.
Neben Instanzvariablen und -methoden können auch Klassenvariablen und -methoden definiert werden. Alle Elemente einer Klassendefinition können mit Hilfe der aus C++ bekannten Schlüsselwörter public, private und protected in ihrer Sichtbarkeit eingeschränkt werden. Es gibt zwar keine friends, aber die Sichtbarkeit von Methoden oder Klassen kann auf das eigene Paket beschränkt werden. Objektvariablen werden als Referenzen implementiert. Mit ihrer Hilfe ist eine gegenüber C/C++ eingeschränkte Zeigerverarbeitung möglich, die das Erstellen dynamischer Datenstrukturen ermöglicht.
Das Speichermanagement in Java erfolgt automatisch. Während das Erzeugen von Objekten (von wenigen Ausnahmen abgesehen) immer einen expliziten Aufruf des new-Operators erfordert, erfolgt die Rückgabe von nicht mehr benötigtem Speicher automatisch. Ein Garbage-Collector , der als niedrigpriorisierter Hintergrundprozess läuft, sucht in regelmäßigen Abständen nach nicht mehr referenzierten Objekten und gibt den durch sie belegten Speicher an das Laufzeitsystem zurück. Viele der Fehler, die bei der Programmierung in C oder C++ dadurch entstehen, dass der Entwickler selbst für das Speichermanagement verantwortlich ist, können in Java nicht mehr auftreten.
In Java gibt es eine strukturierte Ausnahmebehandlung (engl. Exceptionhandling). Damit ist es möglich, Laufzeitfehler zu erkennen und in kontrollierter Weise zu behandeln. Eine Methode muss jeden Laufzeitfehler, der während ihrer Abarbeitung auftreten kann, entweder abfangen oder durch eine geeignete Deklaration an den Aufrufer weitergeben. Dieser hat dann seinerseits die Pflicht, sich um den Fehler zu kümmern. Exceptions sind normale Objekte und die zugehörigen Klassen können erweitert und als Grundlage für anwendungsspezifische Fehler-Objekte verwendet werden.
Eine der am meisten gebrauchten Erklärungen für den frühen Erfolg von Java war die enge Verbindung der Sprache zum World Wide Web. Mit Hilfe von Java ist es möglich, Programme zu entwickeln, die über das Web verbreitet und innerhalb eines Browsers wie Mozilla Firefox, Microsoft Internet Explorer oder Safari ausgeführt werden. Dazu wurde die Sprache HTML um das APPLET-Tag erweitert, um kompilierten Java-Code in normale Webseiten einzubinden.
Ein Java-fähiger Browser enthält einen Java-Interpreter (die virtuelle Java-Maschine, auch kurz VM genannt) und die Laufzeitbibliothek, die benötigt wird, um die Ausführung des Programms zu unterstützen. Die genaue Beschreibung der virtuellen Maschine ist Bestandteil der Java-Spezifikation und Java-VMs sind auf praktisch alle bedeutenden Betriebssystemplattformen portiert worden. Ein Applet kann damit als eine neue Art von Binärprogramm angesehen werden, das über verschiedene Hardware- und Betriebssystemplattformen hinweg portabel ist und auf einfache Weise im Internet verteilt werden kann.
Ein Applet besitzt alle Eigenschaften eines grafischen Ausgabefensters und kann zur Anzeige von Text, Grafik und Dialogelementen verwendet werden. Einer der Vorteile von Applets gegenüber herkömmlichen Programmen ist ihre einfache Verteilbarkeit. Anstelle explizit auszuführender Installationsroutinen lädt der Classloader des Browsers die Bestandteile eines Applets einfach aus dem Netz und führt sie direkt aus. Das ist vor allem bei kleineren und mittelgroßen Anwendungen in einer lokalen Netzwerkumgebung sehr hilfreich, insbesondere wenn diese sich häufig ändern.
Sicherheit war eines der wichtigsten Designziele bei der Entwicklung von Java und es gibt eine ganze Reihe von Sicherheitsmechanismen, die verhindern sollen, dass Java-Applets während ihrer Ausführung Schaden anrichten. So ist es einem Applet, das in einem Web-Browser läuft, beispielsweise nicht erlaubt, Dateioperationen auf dem lokalen Rechner durchzuführen oder externe Programme zu starten.
![]() |
![]() |
Es soll allerdings nicht verschwiegen werden, dass die Applet-Euphorie im Laufe der Zeit deutlich abgeklungen ist. Dies lag einerseits an den Java-Implementierungen der Web-Browser, die mit den JDKs nicht Schritt halten konnten. Zudem legten die Sicherheitsfeatures den Entwicklern oft so große Beschränkungen auf, dass sie die Nützlichkeit von Applets erheblich einschränkten. Der große Erfolg von Java in der Post-1.1-Ära ist eher in der Entwicklung von Applikationen als von Applets zu sehen. Mit der Veröffentlichung der WebStart-Technologie während des JDK 1.3 wurden dann die Vorteile beider Technologien wieder miteinander verbunden. |
![]() |
|
![]() |
Die Java-Laufzeitbibliothek bietet umfassende grafische Fähigkeiten. Diese sind im Wesentlichen plattformunabhängig und können dazu verwendet werden, portable Programme mit GUI-Fähigkeiten auszustatten:
Das AWT stellt eine Reihe von elementaren Operationen zur Verfügung, um grafische Ausgabeelemente, wie Linien, Polygone, Kreise, Ellipsen, Kreisabschnitte oder Rechtecke, zu erzeugen. Diese Methoden können auch in einem Füllmodus verwendet werden, der dafür sorgt, dass die gezeichneten Flächen mit Farbe ausgefüllt werden. Wie in den meisten Grafik-Libraries realisiert auch Java die Bildschirmausgabe mit Hilfe des Konzepts eines Grafikkontexts, der eine Abstraktion des tatsächlichen Ausgabegeräts bildet.
Neben grafischen Elementen kann auch Text ausgegeben und an beliebiger Stelle innerhalb der Fenster platziert werden. Text kann skaliert werden und es ist möglich, mit unterschiedlichen Fonts zu arbeiten. Das AWT bemüht sich, einen portablen Weg zur Font-Auswahl anzubieten, indem eine Reihe von elementaren Schriftarten auch über Plattformgrenzen hinweg angeboten werden. Mit Hilfe von Font-Metriken können numerische Eigenschaften der verwendeten Schriftarten bestimmt und bei der Ausgabe berücksichtigt werden.
Das Farbmodell von Java basiert auf dem RGB-Modell, das seine Farben additiv auf der Basis der enthaltenen Rot-, Grün- und Blauanteile bestimmt. Daneben wird auch das HSB-Modell unterstützt (hue, saturation, brightness) und es gibt Methoden zur Konvertierung zwischen beiden. Das Farbsystem unterstützt eine Reihe von vordefinierten Farben, die plattformübergreifend zur Verfügung stehen.
Neben Grafik kann auch Sound ausgegeben werden und Java unterstützt die Wiedergabe diverser Soundformate. Samples können einmalig abgespielt oder in einer Schleife wiederholt werden. Daneben ist es möglich, zwei oder mehr Sound-Dateien gleichzeitig abzuspielen. Seit dem JDK 1.2 gibt es ein eigenes Sound-API, das neben Wave-Dateien auch Midi-Dateien wiedergeben und bearbeiten kann.
Das AWT erlaubt die Anzeige und Manipulation von Bilddaten. Mit Hilfe von Standardmethoden können Grafiken in elementaren Formaten wie GIF oder JPEG geladen, skaliert und auf dem Bildschirm angezeigt werden. Zusätzlich gibt es das Paket java.awt.image, das für die Manipulation von Bilddaten entworfen wurde und ausgefeilte Funktionen zur Bild- und Farbmanipulation zur Verfügung stellt.
Wie in den meisten grafischen Entwicklungsumgebungen wird auch beim AWT der Programmfluss durch Nachrichten (Events) gesteuert. Sie werden beim Auftreten bestimmter Ereignisse an das Programm gesendet und von diesem in geeigneter Weise behandelt. Java stellt Nachrichten zur Bearbeitung von Maus-, Tastatur-, Fenster-, Dialog- und vielen anderen Ereignissen zur Verfügung. Das Event-Handling erlaubt es, Nachrichten an jedes beliebige Objekt zu senden, das die Schnittstelle eines Nachrichtenempfängers implementiert.
Die zweite grafische Oberfläche des JDK, das Swing-Toolkit, bietet noch weitreichendere Fähigkeiten als das AWT. Dazu wurde eine vollkommen neue Architektur entworfen, in der viele zusätzliche Dialogelemente, wie Tabellen, Trees oder Karteikarten, zur Verfügung stehen. Anstatt wie im AWT auf die Eigenschaften vorgefertigter GUI-Elemente zu vertrauen, verwendet Swing lediglich einen sehr eingeschränkten Satz an plattformspezifischen Grafikoperationen. Alle Dialogelemente werden unter Verwendung einfacher und portabler Grafikprimitive selbst dargestellt. Die Anzahl der Unterschiede zwischen den verschiedenen Plattformen wird auf diese Weise drastisch reduziert und die Swing-Dialogelemente lassen sich wesentlich einfacher und konsistenter auf unterschiedliche Grafiksysteme portieren.
Die Java-Klassenbibliothek bietet mit einer ganzen Reihe nützlicher Klassen und Interfaces die Möglichkeit, sehr problemnah zu programmieren. Einige dieser Features sind von Anfang an nützlich, andere erschließen sich erst nach einer gewissen Einarbeitung.
Neben grafischen Ausgabemöglichkeiten stellt Java auch einfache Textausgaben zur Verfügung, ähnlich den entsprechenden Funktionen in C oder C++. Damit ist es möglich, Programme mit einfachen, zeilenorientierten Ein-/Ausgabemöglichkeiten auszustatten, wenn keine aufwändige Benutzerschnittstelle benötigt wird.
Eines der wichtigsten Elemente der Klassenbibliothek ist die Klasse String, die Java-Implementierung von Zeichenketten. String bietet eine Vielzahl wichtiger Methoden zur Manipulation und zum Zugriff auf Zeichenketten, wie beispielsweise Operationen für numerische Konvertierungen, Zeichen- und Teilstringextraktion sowie für Textsuche und Stringvergleich.
Eine List in Java ist eine lineare Liste, die jede Art von Objekt aufnehmen kann und auf deren Elemente sowohl sequenziell als auch wahlfrei zugegriffen werden kann. Die Länge einer Liste ist veränderlich und Elemente können am Ende oder an einer beliebigen anderen Stelle eingefügt werden. Wie gewöhnlich erfolgt auch das Speichermanagement einer Liste vollkommen automatisch. Neben List gibt es weitere Container-Klassen. So bietet beispielsweise Map die Möglichkeit, Schlüssel-Wert-Paare zusammenhängend zu speichern und bei gegebenem Schlüssel den zugehörigen Wert effizient wieder aufzufinden.
Ein nützlicher Mechanismus zum Durchlaufen von Container-Klassen ist das Iterator-Interface, das die Methoden hasNext() und next() zur Verfügung stellt. Diese können verwendet werden, um in einer Schleife alle Elemente des Containers sukzessive zu durchlaufen. Alle vordefinierten Container-Klassen stellen Methoden zur Verfügung, die Iterator-Objekte zum Durchlaufen der eigenen Elemente zurückgeben.
Seit dem JDK 1.1 werden darüber hinaus mit jedem Release weitere hochspezialisierte (und teilweise sehr aufwändige) Bibliotheken zur Verfügung gestellt. So bietet beispielsweise JDBC (Java Database Connectivity) den Zugriff auf relationale Datenbanken, das JPA (Java Persistence API) erlaubt dies sogar vollständig objektorientiert. Mit JavaBeans steht eine portable Komponentenarchitektur zur Verfügung und mit dem Networking-API und RMI (Remote Method Invocation) kann unternehmensweit auf Netzwerkressourcen und verteilte Objekte zugegriffen werden. Per Serialisierung können nahezu beliebige Objekte dauerhaft gespeichert werden und mit dem Reflection-API kann der Aufbau von Objekten und Klassen zur Laufzeit untersucht und dynamisch darauf zugegriffen werden. Zu guter Letzt gibt es Bibliotheken zum Lesen und zum Schreiben von XML-Dateien.
Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0 |
<< | < | > | >> | API | © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de |