|
|
.JAVA GLOSSAR T-Z
T
Bei this handelt
es sich um einen Zeiger, der beim Anlegen eines Objekts automatisch
generiert wird. this ist eine Referenzvariable, die auf das
aktuelle Objekt zeigt und dazu verwendet wird, die eigenen
Methoden und Instanzvariablen
anzusprechen. Der this-Zeiger ist auch explizit verfügbar
und kann wie eine ganz normale Objektvariable
verwendet werden. Er wird als versteckter Parameter an jede
nicht-statische Methode übergeben. Manchmal ist es sogar
sinnvoll, this explizit zu verwenden, auch wenn es nicht unbedingt
erforderlich ist. Dadurch wird hervorgehoben, dass es sich
um den Zugriff auf eine Instanzvariable,
und nicht eine lokale Variable,
handelt.
Lokale Variablen
verdecken gleichnamige Instanz-
oder Klassenvariablen. Durch
Voranstellen des this-Zeigers kann trotzdem auf sie zugegriffen
werden. Dies wird in Java oft ausgenutzt, um im Konstruktor
einer Methode Membervariablen
zu initialisieren, die denselben Namen wie formale Parameter
haben.
Unterschiedliche Konstruktoren
einer Klasse können in Java verkettet werden, d.h. sie
können sich gegenseitig aufrufen. Der aufzurufende Konstruktor
wird dabei als eine normale Methode angesehen, die über
den Namen this aufgerufen werden kann. Die Unterscheidung
zum bereits vorgestellten this-Pointer nimmt der Compiler
anhand der runden Klammern vor, die dem Aufruf folgen. Alternativ
zu diesen beiden Varianten, einen Superklassenkonstruktor
aufzurufen, ist es auch erlaubt, mit Hilfe der this-Methode
einen anderen Konstruktor der
eigenen Klasse aufzurufen. Um die oben erwähnten Zusagen
einzuhalten, muss dieser allerdings selbst direkt oder indirekt
schließlich einen Superklassenkonstruktor aufrufen.
|
|
Kaum eine wichtige
Programmiersprache der letzten Jahre hat das Konzept der Nebenläufigkeit
innerhalb der Sprache implementiert. Mit Nebenläufigkeit
bezeichnet man die Fähigkeit eines Systems, zwei oder
mehr Vorgänge gleichzeitig oder quasi-gleichzeitig ausführen
zu können. Lediglich ADA stellt sowohl parallele Prozesse
als auch Mechanismen zur Kommunikation und Synchronisation
zur Verfügung, die direkt in die Sprache eingebettet
sind. Durch Weiterentwicklungen im Bereich der Betriebssystemtechnologie
wurde allerdings das Konzept der Threads immer populärer
und auf der Basis von Library-Routinen auch konventionellen
Programmiersprachen zur Verfügung gestellt.
Java hat Threads direkt in die Sprache integriert
und mit den erforderlichen Hilfsmitteln als Konstrukt zur
Realisierung der Nebenläufigkeit implementiert. Ein Thread
ist ein eigenständiges Programmfragment, das parallel
zu anderen Threads laufen kann. Ein Thread ähnelt damit
einem Prozess, arbeitet aber auf einer feineren Ebene. Während
ein Prozess das Instrument zur Ausführung eines kompletten
Programms ist, können innerhalb dieses Prozesses mehrere
Threads parallel laufen. Der Laufzeit-Overhead zur Erzeugung
und Verwaltung eines Threads ist relativ gering und kann in
den meisten Programmen vernachlässigt werden. Ein wichtiger
Unterschied zwischen Threads und Prozessen ist der, dass alle
Threads eines Programmes sich einen gemeinsamen Adressraum
teilen, also auf dieselben Variablen
zugreifen, während die Adressräume unterschiedlicher
Prozesse streng voneinander getrennt sind.
Die Implementierung von Threads war eine
explizite Anforderung an das Design der Sprache. Threads sollen
unter anderem die Implementierung grafischer Anwendungen erleichtern,
die durch Simulationen komplexer Abläufe oft inhärent
nebenläufig sind. Threads können auch dazu verwendet
werden, die Bedienbarkeit von Dialoganwendungen zu verbessern,
indem rechenintensive Anwendungen im Hintergrund ablaufen.
Threads werden in Java durch die Klasse Thread
und das Interface Runnable
implementiert. In beiden Fällen wird der Thread-Body,
also der parallel auszuführende Code, in Form der überlagerten
Methode run zur Verfügung gestellt. Die Kommunikation
kann dann durch Zugriff auf die Instanz-
oder Klassenvariablen oder durch
Aufruf beliebiger Methoden, die
innerhalb von run sichtbar sind, erfolgen. Zur Synchronisation
stellt Java das aus der Betriebssystemtheorie bekannte Konzept
des Monitors zur Verfügung, das es erlaubt, kritische
Abschnitte innerhalb korrekt geklammerter Programmfragmente
und Methoden zu kapseln und so
den Zugriff auf gemeinsam benutzte Datenstrukturen zu koordinieren.
Darüber hinaus bietet Java Funktionen
zur Verwaltung von Threads. Diese erlauben es, Threads in
Gruppen zusammenzufassen, zu priorisieren und Informationen
über Eigenschaften von Threads zu gewinnen. Das Scheduling
kann dabei wahlweise unterbrechend oder nichtunterbrechend
implementiert sein. Die Sprachspezifikation legt dies nicht
endgültig fest, aber in den meisten Java-Implementierungen
wird dies von den Möglichkeiten des darunter liegenden
Betriebssystems abhängen.
[Verwalten von Threads]
|
|
Mit Hilfe der throw-Anweisung
kann ein Objekt dazu verwendet werden, eine Ausnahme zu erzeugen.
Die Syntax der throw-Anweisung ist:
throw AusnahmeObjekt;
Die Behandlung von Fehlern folgt den üblichen
Regeln. Sie entspricht damit genau dem Fall, wenn anstelle
der throw-Anweisung eine aufgerufene Methode denselben Fehler
ausgelöst hätte: Zunächst wird in den umgebenden
Blöcken nach einem Fehler-Handler gesucht. Falls das
erfolglos ist, wird der Fehler an den Aufrufer weitergegeben.
Die throw-Anweisung kann nicht nur dazu verwendet
werden, neue Fehler auszulösen. Sie kann ebenfalls eingesetzt
werden, um innerhalb der catch-Klausel
einer try-catch-Anweisung das
übergebene Fehlerobjekt erneut zu senden. In diesem Fall
wird nicht noch einmal dieselbe catch-Klausel
ausgeführt, sondern der Fehler wird gemäß
den oben genannten Regeln an den umgebenden Block bzw. den
Aufrufer weitergegeben.
Auch selbstdefinierte Ausnahmen müssen
sich an die catch-or-throw-Regel
halten. Wird die Ausnahme nicht innerhalb derselben Methode
behandelt, ist sie mit Hilfe der throws-Klausel
im Methodenkopf zu deklarieren und weiter oben in der Aufrufkette
zu behandeln.
|
|
Das Schlüsselwort
throws deklariert Ausnahmen, die während der Methodenausführung
auftreten können. Sie entstehen durch Programmfehler,
undefinierte Zustände oder treten auf, wenn unvorhergesehene
Ereignisse eintreten (Datei nicht verfügbar, Speicher
erschöpft oder ähnliches). Da alle Fehler, die nicht
innerhalb einer Methode behandelt werden, dem Compiler mit
Hilfe der throws-Klausel bekanntgemacht werden, kennt dieser
zu jeder Methode die potentiellen Fehler, die von ihr verursacht
werden können. Mit diesen Informationen kann der Compiler
bei jedem Methodenaufruf sicherstellen, dass der Aufrufer
seinerseits die catch-or- throw-Regel
einhält. |
|
Der Datentyp boolean
kennt zwei verschiedene Werte, nämlich true und false.
Neben den vordefinierten Konstanten gibt es keine weiteren
Literale für logische Datentypen. |
|
try
|
Die try-catch-Anweisung
|
Der try-Block enthält
dabei eine oder mehrere Anweisungen, bei deren Ausführung
ein Fehler des Typs Ausnahmetyp auftreten kann. In diesem
Fall wird die normale Programmausführung unterbrochen,
und der Programmablauf fährt mit der ersten Anweisung
nach der catch-Klausel fort,
die den passenden Ausnahmetyp deklariert hat. Hier kann nun
Code untergebracht werden, der eine angemessene Reaktion auf
den Fehler realisiert. |
|
Ebenso wie in C gibt
es auch in Java einen Type-Cast-Operator, mit dessen Hilfe
explizite Typumwandlungen vorgenommen werden können.
Der Ausdruck (type) a wandelt den Ausdruck a in einen Ausdruck
vom Typ type um. Auch wenn a eine Variable ist, ist das Ergebnis
von (type) a ein Ausdruck, der nicht mehr auf der linken,
sondern nur noch auf der rechten Seite eines Zuweisungsoperators
stehen darf.
Es gibt verschiedene Arten von Typkonvertierungen
in Java. Mit Hilfe des Type-Cast-Operators dürfen alle
legalen Typkonvertierungen vorgenommen werden. Der Type-Cast-Operator
wird vor allem dann angewendet, wenn der Compiler keine impliziten
Konvertierungen vornimmt; beispielsweise bei der Zuweisung
von größeren an kleinere numerische Typen oder
bei der Umwandlung von Objekttypen.
|
|
U
In Java ist es erlaubt,
Methoden zu überladen, d.h.
innerhalb einer Klasse zwei unterschiedliche Methoden
mit demselben Namen zu definieren. Der Compiler unterscheidet
die verschiedenen Varianten anhand der Anzahl und der Typisierung
ihrer Parameter. Haben zwei Methoden
denselben Namen, aber unterschiedliche Parameterlisten, werden
sie als verschieden angesehen. Es ist dagegen nicht erlaubt,
zwei Methoden mit exakt demselben
Namen und identischer Parameterliste zu definieren.
Der Rückgabetyp einer Methode
trägt nicht zu ihrer Unterscheidung bei. Zwei Methoden,
die sich nur durch den Typ ihres Rückgabewertes unterscheiden,
werden also als gleich angesehen. Da Methoden
auch ohne die Verwendung ihres Rückgabewerts aufgerufen
werden können (was typischerweise wegen ihrer Nebeneffekte
geschieht), hätte weder der Compiler noch der menschliche
Leser in diesem Fall die Möglichkeit, festzustellen,
welche der überladenen Varianten tatsächlich aufgerufen
werden soll.
Das Überladen von Methoden
ist dann sinnvoll, wenn die gleichnamigen Methoden auch eine
vergleichbare Funktionalität haben. Eine typische Anwendung
von überladenen Methoden
besteht in der Simulation von variablen Parameterlisten (die
als Feature direkt in Java nicht zur Verfügung stehen).
Auch, um eine Funktion, die bereits an vielen verschiedenen
Stellen im Programm aufgerufen wird, um einen weiteren Parameter
zu erweitern, ist es nützlich, diese Funktion zu überladen,
um nicht alle Aufrufstellen anpassen zu müssen.
|
|
Neben den Membervariablen
erbt eine abgeleitete Klasse auch die Methoden
ihrer Vaterklasse (wenn dies
nicht durch spezielle Attribute verhindert wird). Daneben
dürfen auch neue Methoden
definiert werden. Die Klasse besitzt dann alle Methoden,
die aus der Vaterklasse geerbt
wurden, und zusätzlich die, die in der Methode
neu definiert wurden. Daneben dürfen auch bereits von
der Vaterklasse geerbte Methoden
neu definiert werden. In diesem Fall spricht man von Überlagerung
der Methode. Wurde eine Methode überlagert, wird beim
Aufruf der Methode auf Objekten dieses Typs immer die überlagernde
Version verwendet. |
|
V
Variablen dienen
dazu, Daten im Hauptspeicher eines Programms abzulegen und
gegebenenfalls zu lesen oder zu verändern. In Java gibt
es drei Typen von Variablen:
· Instanzvariablen,
die im Rahmen einer Klassendefinition definiert und zusammen
mit dem Objekt angelegt werden.
· Klassenvariablen,
die ebenfalls im Rahmen einer Klassendefinition definiert
werden, aber unabhängig von einem konkreten Objekt existieren.
· Lokale
Variablen, die innerhalb einer Methode
oder eines Blocks definiert werden und nur dort existieren.
Daneben betrachtet die Sprachdefinition auch
Array-Komponenten und die Parameter von Methoden und Exception-Handlern
als Variablen.
Eine Variable in Java ist immer typisiert.
Sie ist entweder von einem primitiven Typen oder von einem
Referenztypen. Mit Ausnahme eines Spezialfalls bei Array-Variablen,
auf den wir später zurückkommen, werden alle Typüberprüfungen
zur Compile-Zeit vorgenommen. Java ist damit im klassischen
Sinne eine typsichere Sprache. Die Deklaration einer Variable
erfolgt in der Form:
Typname Variablenname;
Typname VariablenName = InitialerWert;
Die Deklaration einer lokalen Variable gilt in Java als ausführbare
Anweisung. Sie darf daher überall dort erfolgen, wo eine
Anweisung verwendet werden darf. Die Sichtbarkeit einer lokalen
Variable erstreckt sich von der Deklaration bis zum Ende des
umschließenden Blocks.
Lokale Variablen
dürfen sich nicht gegenseitig verdecken. Es ist also
nicht erlaubt, eine bereits deklarierte Variable x in einem
tiefer geschachtelten Block erneut zu deklarieren. Das Verdecken
von Klassen- oder Instanzvariablen
dagegen ist zulässig und wird besonders häufig in
Konstruktoren bei der Initialisierung
von Instanzvariablen verwendet.
|
|
Vaterklasse
|
Generalisierung und Spezialisierung |
"is-a"-Beziehungen werden in
objektorientierten Programmiersprachen durch Vererbung
ausgedrückt. Eine Klasse wird dabei nicht komplett neu
definiert, sondern von einer anderen Klasse abgeleitet. In
diesem Fall erbt sie alle Eigenschaften dieser Klasse und
kann nach Belieben eigene hinzufügen. In unserem Fall
wäre also B von A abgeleitet. A wird als Basisklasse
(manchmal auch als Vaterklasse), B als abgeleitete Klasse
bezeichnet. |
|
Vererbung ist die
Möglichkeit, Eigenschaften vorhandener Klassen
auf neue Klassen zu übertragen.
Fehlt diese Fähigkeit, bezeichnet man die Sprache auch
als lediglich objektbasiert. Man unterscheidet dabei zwischen
einfacher Vererbung, bei der eine Klasse von maximal einer
anderen Klasse abgeleitet werden kann, und Mehrfachvererbung,
bei der eine Klasse von mehr als einer anderen Klasse abgeleitet
werden kann. In Java gibt es lediglich Einfachvererbung, um
den Problemen aus dem Weg zu gehen, die durch Mehrfachvererbung
entstehen können. Um die Einschränkungen in den
Designmöglichkeiten, die bei Einfachvererbung entstehen,
zu vermeiden, wurde mit Hilfe der Interfaces
eine neue, restriktive Art der Mehrfachvererbung
eingeführt. Wir werden später darauf zurückkommen.
Vererbungen
können mehrstufig sein, d.h. eine abgeleitete Klasse
kann Basisklasse für weitere Klassen sein. Auf diese
Weise können vielstufige Vererbungshierarchien entstehen,
die in natürlicher Weise die Taxonomie (also die gegliederte
Begriffsstruktur) der zu modellierenden Anwendungswelt repräsentieren.
Vererbungshierarchien werden wegen ihrer Baumstruktur auch
als Ableitungsbäume bezeichnet. Sie werden meist durch
Graphen dargestellt, in denen die abgeleiteten Klassen
durch Pfeile mit den Basisklassen verbunden sind und die Basisklassen
oberhalb der abgeleiteten Klassen
stehen.
|
|
Threads
können in Java nicht nur ausgeführt und synchronisiert
werden, sondern besitzen auch eine Reihe administrativer Eigenschaften,
die besonders dann nützlich sind, wenn das Thread-Konzept
stark genutzt wird. Diese administrativen Eigenschaften lassen
sich in zwei Gruppen unterteilen. Zum einen gibt es Eigenschaften,
die bei den Threads selbst zu
finden sind, beispielsweise die Priorität oder der Name
eines Threads. Zum anderen gibt
es Eigenschaften, die darauf begründet sind, dass jeder
Thread in Java zu einer Thread-Gruppe
gehört, die untereinander über Vater-Kind-Beziehungen
miteinander in Verbindung stehen. |
|
Methoden
können selbstverständlich Nebeneffekte haben und
werden in vielen Fällen ausschließlich zu diesem
Zweck geschrieben. Ist dies der Fall, so sollte eine Methode
als void deklariert werden und damit anzeigen, dass sie keinen
Rückgabewert produziert. Die einzig sinnvolle Verwendung
einer solchen Methode besteht darin, sie innerhalb einer Ausdrucksanweisung
aufzurufen, da sie nicht in Ausdrücken verwendet werden
dürfen. Hat eine Methode einen Rückgabewert (ist
also nicht vom Typ void), so kann sie mit Hilfe der return-Anweisung
einen Wert an den Aufrufer zurückgeben.
Jede Methode in Java ist typisiert. Der Typ
einer Methode wird zum Zeitpunkt der Definition festgelegt
und bestimmt den Typ des Rückgabewerts. Dieser kann von
einem beliebigen primitiven Typ, einem Objekttyp (also einer
Klasse) oder vom Typ void sein. [return]
|
|
W
Die Klasse Window
abstrahiert ein Top-Level-Window ohne Rahmen, Titelleiste
und Menü. Sie ist für Anwendungen geeignet, die
ihre Rahmenelemente selbst zeichnen oder die volle Kontrolle
über das gesamte Fenster benötigen.
Das Abstract Windowing Toolkit von Java enthält
verschiedene Fensterklassen, die über eine gemeinsame
Vererbungshierarchie miteinander
in Verbindung stehen. Oberste Fensterklasse ist Component,
daraus wurde Container abgeleitet. Container ist die Oberklasse
der beiden Klassen Window und Panel. Während Window sich
in die Unterklassen Frame und Dialog verzweigt, wird aus Panel
die Klasse Applet abgeleitet.
Unterhalb von Dialog gibt es noch den Standard-File-Dialog
in der Klasse FileDialog.
Zum Ableiten einer eigenen Fensterklasse
wird in der Regel entweder die Klasse Frame oder die Klasse
Dialog verwendet, die beide aus Window abgeleitet sind. Dialog
wird vorwiegend dafür verwendet, Dialogboxen zu erstellen,
um die dafür vorgesehen, modale oder nicht-modale Dialoge
zu realisieren (die über enthaltene Komponenten mit dem
Anwender kommunizieren). Ein modaler Dialog ist ein Fenster,
das immer im Vordergrund des Fensters bleibt, von dem es erzeugt
wurde, und das alle übrigen Fensteraktivitäten und
Ereignisse so lange blockiert, bis es geschlossen wird. Ein
nicht-modaler Dialog kann mit anderen Fenstern koexistieren
und erlaubt es, im aufrufenden Fenster weiterzuarbeiten.Die
wichtigste Klasse zur Ausgabe von Grafiken in Java-Applikationen
ist Frame.
|
|
Ein Window-Event
wird immer dann generiert, wenn sich am Status eines Fensters
eine Änderung ergeben hat, die für das Anwendungsprogramm
von Interesse sein könnte. So erlangt das Programm beispielsweise
Kenntnis davon, wenn ein Fenster erstellt oder zerstört,
aktiviert oder deaktiviert oder wenn es symbolisiert oder
wiederhergestellt wird.
Ein Empfänger für Window-Events
muss das Interface WindowListener
implementieren und bekommt Events des Typs WindowEvent
übergeben. WindowEvent erweitert die Klasse ComponentEvent
und stellt neben getID und getSource die Methode getWindow
zur Verfügung, mit der das Fenster ermittelt werden kann,
das die Nachricht ausgelöst hat. Die Registrierung der
Empfängerklasse erfolgt mit der Methode addWindowListener,
die in den Klassen Dialog und Frame zur Verfügung steht.
|
|
Zu jedem primitiven
Datentyp in Java (numerischen Typen, char und boolean)
gibt es eine korrespondierende Wrapper-Klasse. Diese kapselt
die primitive Variable in einer objektorientierten Hülle
und stellt eine Reihe von Methoden
zum Zugriff auf die Variable zur Verfügung. Zwar wird
man bei der Programmierung meist die primitiven Typen verwenden,
doch gibt es einige Situationen, in denen die Anwendung einer
Wrapper-Klasse sinnvoll sein kann:
· Das Paket
java.util stellt eine Reihe von Verbundklassen zur Verfügung,
die beliebige Objekttypen speichern können. Um darin
auch elementare Typen ablegen zu können, ist es notwendig,
anstelle der primitiven Typen ihre Wrapper-Klassen zu verwenden.
· Da Objektreferenzen den Wert null
haben können, kann die Verwendung der Wrapper-Klassen
beispielsweise bei der Datenbankprogrammierung nützlich
sein. Damit lassen sich primitive Feldtypen darstellen, die
NULL-Werte enthalten können.
· Das Reflection-API verwendet Wrapper-Klassen
zum Zugriff auf Membervariablen
oder Methodenargumente primitiver Typen.
Die Instanzierung einer Wrapper-Klasse kann
meist auf zwei unterschiedliche Arten erfolgen. Einerseits
ist es möglich, den korrespondierenden primitiven Typ
an den Konstruktor zu übergeben,
um ein Objekt desselben Werts zu erzeugen. Alternativ kann
meist auch ein String an den
Konstruktor übergeben werden.
Dieser wird in den entsprechenden primitiven Typ konvertiert
und dann zur Initialisierung
der Wrapper-Klasse verwendet.
[Call by Reference]
|
|
X
Y
Z
Quelle: Java - Glossary zusammengestellt aus „Go To Java 2“,
Zweite Auflage, Addison Wesley, Version 2.0 © 2000 Guido Krüger
|
|