Die Class
Instanceof
Alle Objekte kennen ihre eigene Klasse, die Sie mit getClass() erfragen können. Sie erhalten ein statisches Objekt der Klasse java.lang.Class, also eine Konstante vom Type Class (genau wie public static final String MY_NAME="Hans"). Auch diese Konstante hat einen Namen, nämlich „class", und sie kann auch so benutzt werden.
Object obj=new Frame();
System.out.println(obj.getClass().equals( Frame.class));
Die Ausgabe ist true.
Viele Schnittstellen sind auf java.lang.Object definiert, obwohl in Wirklichkeit natürlich Objekte anderer Klassen übergeben werden (Beispiele: java.lang.Object#clone(), java.lang.Comparable#compareTo(Object), Object java.util.Iterator#next()usw.). Daher muss man häufig casten, um das Object in seine ursprüngliche Klasse zurück zu verwandeln.
Dabei besteht das Risiko einer java.lang.ClassCastExcepiton, d.h. eines Laufzeitfehlers, wenn das Objekt nicht der erwarteten Klasse entspricht. Es gibt daher eine verkürzte Schreibweise, um die Klasse eines Objekts abzufragen und anschliessend zu casten:
if (obj instanceof Frame){
Frame f=(Frame) obj;
}
Instanceof ist ein Operator, der auf die class –Eigenschaft eines Objekts prüft und einen Wahrheitswert zurückgibt. Die gesuchte Klasse wird dabei wie im Beispiel gezeigt ohne die .class – Erweiterung angeben.
Dynamisches Laden
Class bietet Zugriff auf den Class-Loader und damit die Möglichkeit, Klassen und Ressourcen zur Laufzeit zu laden. So könnte man beispielsweise beim Starten eines Programms zwischen verschiedenen Implementierungen eines Interfaces wählen und so unterschiedliches Verhalten des Programms erzeugen (Plug-In-Mechanismus). Eine Anwendung hierfür sind beispielsweise Datenbanktreiber, sodass ein Programm mit unterschiedlichen Datenbanken arbeiten kann, ohne dass der Code geändert werden muss, wenn der entsprechende Treiber zur Laufzeit geladen wird.
Um eine Klasse dynamisch zu laden, holt man sich in einem ersten Schritt das ein Class – Objekt der entsprechenden Klasse mit der statischen Methode: Class.forName(String);
Class buttonClass=Class.forName(„java.awt.Button");
Das Class-Objekt kann dann in einem zweiten Schritt eine Instanz der Klasse erzeugen.
Button b=(Button)buttonClass.newInstance();
Das funktioniert allerdings nur, wenn die Klasse einen parameterlosen Konstruktor anbietet. Allerdings tun dies alle UI-Klassen, sodass hier kein Risiko besteht. Unsere Beispielapplikation DynamicLoading nimmt einen Klassennamen entgegen und instanziert ein entsprechendes Objekt.
Führen Sie das Programm aus und geben Sie verschiedeneAWT-Klassen ein, um die Wirkung zu testen (java.awt.Button, java.awt.Label, java.awt.TextArea, java.awt.TextField usw.). Geben Sie auch einen nicht existierenden Klassennamen ein, um zu sehen, wie das Programm sich im Falle eines Fehlers verhält. Studieren Sie den Quellcode der refresh() - Methode und vollziehen Sie die einzelnen Schritte beim dynamischen erzeugen des Objekts anhand der Kommentare nach.
Introspektive
Class kann aber noch mehr! Wie Sie anhand des obigen Beispiels erkennen, kennt Class auch alle Methoden der instanzierten Klasse. Im Beispiel holen wir uns alle Methoden als Methoden-Array mit:
java.lang.reflect.Method[]=c.getClass().getMethods();
Die Klasse java.lang.reflect.Method stammt aus dem Reflections - Paket, das speziell dazu dient, Informationen über Klassen zur Laufzeit zu erhalten. Wir fragen anschliessend den Namen der Methode ab (method.getName()) und führen gegebenenfalls diese Methode aus:
method.invoke(obj, params);
wobei wir das Objekt, zu dem diese Methode gehört, übergeben, sowie ein passendes Array von Parametern der Methode. Auch Anzahl und Klasse der Parameter könnten wir aus Methoderfragen. Im Beispiel kennen wir die Parameter allerdings schon, sodass wir darauf verzichten können.
Neben den Methoden ermöglicht Class auch den Zugriff auf die Felder, Konstruktoren, Interfaces und Elternklassen eines Objekts. Class ist daher auch für die Tool-Bauer eine interessante Klasse, denn sie bildet die Basis für eine Reihe von Entwicklungswerkzeugen, Klassenbrowsern und GUI-Buildern.
Hinweis: Sie könnten nun das Kapitel über grafische Benutzerschnittstellen (AWT) bearbeiten, um mehr über Buttons und Labels zu erfahren. Über die try - catch Konstruktion mehr im Kapitel Exceptions.