Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Generics, innere Klassen
10 Die Klassenbibliothek
11 Threads und nebenläufige Programmierung
12 Datenstrukturen und Algorithmen
13 Raum und Zeit
14 Dateien und Datenströme
15 Die eXtensible Markup Language (XML)
16 Grafische Oberflächen mit Swing
17 Grafikprogrammierung
18 Netzwerkprogrammierung
19 Verteilte Programmierung mit RMI und Web–Services
20 JavaServer Pages und Servlets
21 Applets
22 Midlets und die Java ME
23 Datenbankmanagement mit JDBC
24 Reflection und Annotationen
25 Logging und Monitoring
26 Sicherheitskonzepte
27 Java Native Interface (JNI)
28 Dienstprogramme für die Java-Umgebung
Stichwort

Download:
- ZIP, ca. 14,1 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel (8. Auflage) von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel (8. Auflage)

Java ist auch eine Insel (8. Aufl.)
8., aktual. Auflage, geb., mit DVD
1.475 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1371-4
Pfeil 24 Reflection und Annotationen
Pfeil 24.1 Metadaten
Pfeil 24.1.1 Metadaten durch JavaDoc-Tags
Pfeil 24.2 Metadaten der Klassen mit dem Class-Objekt
Pfeil 24.2.1 An ein Class-Objekt kommen
Pfeil 24.2.2 Was das Class-Objekt beschreibt
Pfeil 24.2.3 Der Name der Klasse
Pfeil 24.2.4 instanceof mit Class-Objekten
Pfeil 24.2.5 Oberklassen finden
Pfeil 24.2.6 Implementierte Interfaces einer Klasse oder eines Interfaces
Pfeil 24.2.7 Modifizierer und die Klasse Modifier
Pfeil 24.2.8 Die Arbeit auf dem Feld
Pfeil 24.3 Attribute, Methoden und Konstruktoren
Pfeil 24.3.1 Reflections – Gespür für Attribute einer Klasse
Pfeil 24.3.2 Methoden einer Klasse erfragen
Pfeil 24.3.3 Properties einer Bean erfragen
Pfeil 24.3.4 Konstruktoren einer Klasse
Pfeil 24.3.5 Annotationen
Pfeil 24.4 Objekte erzeugen und manipulieren
Pfeil 24.4.1 Objekte erzeugen
Pfeil 24.4.2 Die Belegung der Variablen erfragen
Pfeil 24.4.3 Eine generische toString()-Funktion
Pfeil 24.4.4 Variablen setzen
Pfeil 24.4.5 Private Attribute ändern
Pfeil 24.5 Methoden aufrufen
Pfeil 24.5.1 Statische Methoden aufrufen
Pfeil 24.5.2 Dynamische Methodenaufrufe bei festen Methoden beschleunigen
Pfeil 24.6 Annotationen
Pfeil 24.6.1 Neue Annotationen definieren
Pfeil 24.6.2 Annotationen mit genau einem Element
Pfeil 24.6.3 Beliebige Schlüssel-Werte-Paare
Pfeil 24.6.4 Vorbelegte Elemente
Pfeil 24.6.5 Annotieren von Annotationstypen
Pfeil 24.6.6 Annotationen zur Laufzeit auslesen
Pfeil 24.6.7 Mögliche Nachteile von Annotationen
Pfeil 24.6.8 XDoclet
Pfeil 24.7 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

24.5 Methoden aufrufen Zur nächsten ÜberschriftZur vorigen Überschrift

Nach dem Abfragen und Setzen von Variablenwerten und Konstruktor-Aufrufen zum Erzeugen eines Objekts ist das Aufrufen von Methoden per Reflection der letzte Schritt. Wenn zur Compile-Zeit der Name der Methode nicht feststeht, lässt sich zur Laufzeit dennoch eine im Programm definierte Methode aufrufen, wenn ihr Name als Zeichenkette vorliegt.

Zunächst gehen wir wieder von einem Class-Objekt aus, das die Klasse des Objekts beschreibt, für das eine Objektmethode aufgerufen werden soll. Anschließend wird ein Method-Objekt als Beschreibung der gewünschten Methode benötigt; wir bekommen dies mit der Methode getMethod() aus dem Class-Exemplar. getMethod() verlangt zwei Argumente: einen String mit dem Namen der Methode und ein Array von Class-Objekten. Jedes Element dieses Arrays entspricht einem Parametertyp aus der Signatur der Methode. Damit werden überladene Methoden unterschieden. Nachdem wir das beschreibende Method-Exemplar und die Parameterwerte für den Aufruf vorbereitet haben, ruft invoke() die Zielmethode auf – im Englischen heißt dies dynamic invocation. invoke() erwartet zwei Argumente: ein Array mit Argumenten, die der aufgerufenen Methode übergeben werden, und eine Referenz auf das Objekt, auf dem die Methode aufgerufen werden soll und zur Auflösung der dynamischen Bindung dient.


final class java.lang.reflect.Method 
extends AccessibleObject 
implements GenericDeclaration, Member

  • Object invoke( Object obj, Object... args ) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException Ruft eine Methode des Objekts obj mit den gegebenen Argumenten auf. Wie schon beim Konstruktor löst die Methode eine InvocationTargetException aus, wenn die aufzurufende Methode eine Exception auslöst.

Beispiel Wir erzeugen ein Point-Objekt und setzen im Konstruktor den x-Wert auf 10. Anschließend fragen wir mit der Methode getX(), die wir dynamisch aufrufen, den x-Wert wieder ab.

Listing 24.17 com/tutego/insel/meta/InvokeMethod.java, main()

Point p = new Point( 10, 0 ); 
Method method = p.getClass().getMethod( "getX" ); 
String returnType = method.getReturnType().getName(); 
Object returnValue = method.invoke( p ); 
System.out.printf( "(%s) %s", returnType, returnValue ); // (double) 10.0

Beispiele der Varargs sind bei getMethod() die Parametertypen und bei invoke() die Argumente für setLocation(). Da getMethod() eine beliebige Anzahl von Argumenten annehmen kann und kein Argument dazuzählt, muss die Methode nicht so parametrisiert werden:

Method method = p.getClass().getMethod( "getX", (Class[]) null );

Auffälliger ist die Möglichkeit der variablen Argumentanzahl bei invoke(). Da ein Getter keine Parameter besitzt, heißt es kurz method.invoke(p); statt wie vor Java 5:

method.invoke( p, (Object[]) null );

Interessant sind Methoden mit Parameterliste, wie setLocation():

Point p = new Point(); 
Method method = p.getClass().getMethod( "setLocation", int.class, int.class ); 
method.invoke( p, 1, 2 ); 
System.out.println( p );

Galileo Computing - Zum Seitenanfang

24.5.1 Statische Methoden aufrufen Zur nächsten ÜberschriftZur vorigen Überschrift

Wir wollen ein Beispiel programmieren, in dem die Klasse InvokeMain die main()-Funktion einer anderen Klasse, HasMain, mit einem Parameter aufruft.

Listing 24.18 com/tutego/insel/meta/InvokeMain.java

package com.tutego.insel.meta; 
 
import java.lang.reflect.*; 
import java.util.Arrays; 
 
public class InvokeMain 
{ 
  public static void main( String[] args ) throws Exception 
  { 
    String[] argv = { "-option", "Parameter" }; 
 
    Method method = Class.forName( "com.tutego.insel.meta.HasMain" ). 
                       getMethod( "main", argv.getClass() ); 
 
    method.invoke( null, new Object[]{ argv } ); 
  } 
} 
 
class HasMain 
{ 
  public static void main( String[] args ) 
  { 
    System.out.println( "Got: " + Arrays.toString( args ) ); 
  } 
}

Galileo Computing - Zum Seitenanfang

24.5.2 Dynamische Methodenaufrufe bei festen Methoden beschleunigen topZur vorigen Überschrift

Werden über Reflection Methoden aufgerufen, deren Methodennamen erst zur Laufzeit bestimmt werden, so verlieren wir die Typsicherheit vom Compiler, und die Geschwindigkeit ist nicht optimal – auch wenn es seit Java 5 nicht mehr so schlimm ist. (Doch immer noch zeigt eine einfache Zeitmessung einen deutlichen Unterschied.) Diese Aufrufe lassen sich prinzipbedingt auch durch einen JIT-Compiler nicht weiter beschleunigen. Wir müssen also nach einer Lösung suchen, mit der wir diese Art von Aufruf beschleunigen können. Ein möglicher Weg hierbei ist, in Kenntnis des Namens der Methode – nennen wir die Methode meth() – den Namen in einer (abstrakten) Oberklasse dem Compiler bereits bekannt zu machen. Reflection ist nur zum Laden einer Unterklasse mit gegebenem Namen nötig; die normale, dynamische Methodenbindung erledigt den Rest – ganz ohne versteckte Schnüre, doppelte Böden oder Spiegel (Reflection).

Versuchen wir, den folgenden Code nach diesem Schema zu ändern:

Listing 24.19 com/tutego/insel/meta/DynamReflection.java, main()

Class<?> clazz = Class.forName("com.tutego.insel.meta.DynamReflectionMethod" ); 
Object o = clazz.newInstance(); 
clazz.getMethod( "meth" ).invoke( o );

DynamReflection ist die Hauptklasse, die die Klasse DynamReflectionMethod über Class. forName() anfordert.

Listing 24.20 com/tutego/insel/meta/DynamReflectionMethod.java

package com.tutego.insel.meta; 
 
public class DynamReflectionMethod 
{ 
  public void meth() 
  { 
    System.out.println( "Bewusste Raucher trinken Filterkaffee" ); 
  } 
}

Über das Class-Objekt erzeugt newInstance() ein neues Exemplar. getMethod() sucht die Beschreibung der Methode meth() heraus, und invoke() ruft die Methode »meth« auf. Hier genau liegt ein kleiner Geschwindigkeitsverlust. Wenn es uns gelänge, um das invoke() herumzukommen, wäre das schon ein großer Fortschritt. Dies schaffen wir, indem wir eine Schnittstelle (oder Oberklasse) für DynamReflectionMethod konstruieren, die genau diese Methode vorschreibt. Die implementierende Klasse (beziehungsweise Unterklasse) wird dann eine Implementierung angeben.

Listing 24.21 com/tutego/insel/meta/DynamAbstract.java

package com.tutego.insel.meta; 
 
interface DynamBase 
{ 
  void meth(); 
} 
 
class DynamBaseMethod implements DynamBase 
{ 
  public void meth() 
  { 
    System.out.println( "Bewusste Raucher trinken Filterkaffee" ); 
  } 
} 
 
public class DynamAbstract 
{ 
  public static void main( String[] args ) throws Exception 
  { 
    Class<?> clazz = Class.forName( "DynamBaseMethod" ); 
    DynamBase o = (DynamBase) clazz.newInstance(); 
    o.meth(); 
  } 
}

DynamBase ist eine Schnittstelle, die zur Übersetzungszeit bekannt ist. Die virtuelle Maschine löst den Aufruf nach den üblichen Regeln der dynamischen Bindung selbst auf. Die Klasse DynamBaseMethod wird ebenfalls erst zur Laufzeit geladen. Wir verstecken hier sehr elegant den Aufwand. Wir haben die gleiche Funktionalität und Flexibilität wie im vorangegangenen Reflection-Beispiel – wenn wir die Möglichkeit, den Klassennamen durch einen String anzugeben, außer Acht lassen –, aber mit der höheren Geschwindigkeit eines konventionellen Methodenaufrufs ohne Reflection.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Java ist auch eine Insel





Java ist auch eine Insel
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Tipp
Zum Katalog: Coding for Fun





 Coding for Fun


 Buchempfehlungen
Zum Katalog: Objektorientierte Programmierung





 Objektorientierte
 Programmierung


Zum Katalog: Einstieg in Eclipse 3.4






 Einstieg in
 Eclipse 3.4


Zum Katalog: Java 6 lernen mit Eclipse






 Java 6 lernen
 mit Eclipse


Zum Katalog: NetBeans Platform 6






 NetBeans
 Platform 6


Zum Katalog: Java und XML






 Java und XML


Zum Katalog: Visual C# 2008






 Visual C# 2008


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de