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?
<< zurück | Galileo Computing / <openbook> / Java-Insel | vor >>
Java ist auch eine Insel (8. Auflage) von Christian Ullenboom Programmieren mit der Java Standard Edition Version 6
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 |
| 24 Reflection und Annotationen
|  | 24.1 Metadaten
|  |  | 24.1.1 Metadaten durch JavaDoc-Tags
|  | 24.2 Metadaten der Klassen mit dem Class-Objekt
|  |  | 24.2.1 An ein Class-Objekt kommen
|  |  | 24.2.2 Was das Class-Objekt beschreibt
|  |  | 24.2.3 Der Name der Klasse
|  |  | 24.2.4 instanceof mit Class-Objekten
|  |  | 24.2.5 Oberklassen finden
|  |  | 24.2.6 Implementierte Interfaces einer Klasse oder eines Interfaces
|  |  | 24.2.7 Modifizierer und die Klasse Modifier
|  |  | 24.2.8 Die Arbeit auf dem Feld
|  | 24.3 Attribute, Methoden und Konstruktoren
|  |  | 24.3.1 Reflections – Gespür für Attribute einer Klasse
|  |  | 24.3.2 Methoden einer Klasse erfragen
|  |  | 24.3.3 Properties einer Bean erfragen
|  |  | 24.3.4 Konstruktoren einer Klasse
|  |  | 24.3.5 Annotationen
|  | 24.4 Objekte erzeugen und manipulieren
|  |  | 24.4.1 Objekte erzeugen
|  |  | 24.4.2 Die Belegung der Variablen erfragen
|  |  | 24.4.3 Eine generische toString()-Funktion
|  |  | 24.4.4 Variablen setzen
|  |  | 24.4.5 Private Attribute ändern
|  | 24.5 Methoden aufrufen
|  |  | 24.5.1 Statische Methoden aufrufen
|  |  | 24.5.2 Dynamische Methodenaufrufe bei festen Methoden beschleunigen
|  | 24.6 Annotationen
|  |  | 24.6.1 Neue Annotationen definieren
|  |  | 24.6.2 Annotationen mit genau einem Element
|  |  | 24.6.3 Beliebige Schlüssel-Werte-Paare
|  |  | 24.6.4 Vorbelegte Elemente
|  |  | 24.6.5 Annotieren von Annotationstypen
|  |  | 24.6.6 Annotationen zur Laufzeit auslesen
|  |  | 24.6.7 Mögliche Nachteile von Annotationen
|  |  | 24.6.8 XDoclet
|  | 24.7 Zum Weiterlesen
## 24.5 Methoden aufrufen 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 );
### 24.5.1 Statische Methoden aufrufen 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 ) );
      }
    }
### 24.5.2 Dynamische Methodenaufrufe bei festen Methoden beschleunigen 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. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Zum Katalog
Java ist auch eine Insel Jetzt bestellen
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Tipp
| Coding for Fun
Buchempfehlungen
| Objektorientierte Programmierung
| Einstieg in Eclipse 3.4
| Java 6 lernen mit Eclipse
| NetBeans Platform 6
| Java und XML
| Visual C# 2008
| IT-Handbuch für Fachinformatiker
| C++ von A bis Z
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

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