Info B VL 14: Java Collections/Reflections Objektorientiere Programmierung in Java 2003 Ute Schmid (Vorlesung) Elmar Ludwig (Übung) FB Mathematik/Informatik, Universität Osnabrück Info B VL 14: Java Collections/Reflections – p.271 Java Collection Klassen Java collection framework in java.util: wichtige Klassen und Interfaces, um mit Collections zu arbeiten Bis Java 1.1: nur Vector (jetzt ArrayList) und HashTable (jetzt HashMap) Zwei Grundtypen von Collections: 1. Collection (Interface): Gruppe von Objekten mit Set (Interface) als Collections ohne Dublikate und List (Interface) als Collection mit geordneten Elementen 2. Map (Interface): Menge von Assoziationen (Mappings) zwischen Objekten. weitere Interfaces: Iterator, ListIterator. Ähnlich zum Enumeration-Interface Info B VL 14: Java Collections/Reflections – p.272 ‘Iterator’ public interface Iterator { boolean hasNext(); // vgl. hasMoreElements() Object next(); // vgl. nextElement() // in Enumeration void remove(); // zusaetzlich } remove() erlaubt sicheres Löschen von Elementen während der Iteration. Gelöscht wird das als letztes von next() gelieferte Element. Modifikation der Collection während ihrer Aufzählung ist mit remove() (und nur mit remove()) möglich! Info B VL 14: Java Collections/Reflections – p.273 Anmerkungen ‘Collections’ Für Objekte eigener Klassen, die in Collections gespeichert werden sollen, sollten die Methoden equals() und hashcode() entsprechend der gewünschten Funktionalität überschrieben werden. Die Klasse Collections liefert statische Methoden und Konstanten, die beim Arbeiten mit Collections nützlich sind. Info B VL 14: Java Collections/Reflections – p.274 Struktur der Collection Klassen java.lang java.util Object AbstractCollection AbstractList AbstractSet Collection <<interface>> Map <<interface>> ArrayList C S Vector C S HashSet C S TreeSet C S LinkedList C S Stack List <<interface>> Set <<interface>> AbstractMap AbstractSequentialList HashMap C S TreeMap C S SortedSet <<interface>> Comparator <<interface>> Iterator <<interface>> ListIterator <<interface>> SortedMap <<interface>> (S: implements Serializable, C: implements Clonable) Info B VL 14: Java Collections/Reflections – p.275 Reflections java.lang.reflect Das Reflection-API repräsentiert (reflektiert) Klassen, Schnittstellen und Objekte in der aktuellem JVM Anwendung: vor allem für Debugger, Class-Browser, GUI-Builder auch Parser Info B VL 14: Java Collections/Reflections – p.276 Methodenübersicht Bestimmung der Klasse eines Objekts. Information über Modifikatoren, Felder, Methoden, Konstruktoren, Oberklassen einer Klasse. Information, welche Konstanten und Methoden-Deklarationen zu einem Interface gehören. Erzeugung einer Instanz einer Klasse, deren Namen erst zur Laufzeit bekannt ist. Zugriff und Belegung eines Objekt-Feldes, auch wenn der Name des Feldes erst zur Laufzeit bekannt ist. Aufruf (Invocation) einer Methode eines Objekts, auch wenn die Methode erst zur Laufzeit bekannt ist. Erzeugen eines neuen Arrays, dessen Grösse und Komponenten-Typ erst zur Laufzeit bekannt sind, und Modifikation von Komponenten. Info B VL 14: Java Collections/Reflections – p.277 Klasse ‘Class’ Klasse Class ist Unterklasse von Object Für jede von der JVM geladene Klasse existiert genau ein Class-Objekt. Dieses Objekt kann durch Aufruf der getClass()-Methode für jede beliebige Instanz besorgt werden. wichtige Methoden: public final class Class extends Object implements Serializable { public static Class forName(String name) throws ClassNotFoundException; public Field[] getFields() throws SecurityException; public Method[] getMethods() throws SecurityException; public Constructor[] getConstructors() throws SecurityException; } Info B VL 14: Java Collections/Reflections – p.278 ‘Method’ public final class Method extends AccessibleObject implements Member { public String getName(); public Class[] getParameterTypes(); public Class getReturnType(); public Object invoke(Object obj, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; // many more } Info B VL 14: Java Collections/Reflections – p.279 ‘Field’ public final class Field extends AccessibleObject implements Member { public String getName(); public Class getType(); public boolean equals(Object obj); public int hashCode(); // many more } Info B VL 14: Java Collections/Reflections – p.280 ‘Constructor’ public final class Constructor extends AccessibleObject implements Member { public String getName(); public Class[] getParameterTypes(); public Class[] getExceptionTypes(); public Object newInstance(Object[] initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException; // many more } Info B VL 14: Java Collections/Reflections – p.281 Inspektion von Klassen Name der Klasse zur Compile-Zeit bekannt: Class c = Circle.class sonst: Circle k = new Circle(); Class c = k.getClass(); Class s = c.getSuperClass(); String st = c.getName(); // voll qualifizierter Name Class d = Class.forName(st); Beispielcode in code/reflections: Abruf weiterer Informationen: Klassenfelder, implementiertes Interface, Konstruktoren, Methoden-Information Info B VL 14: Java Collections/Reflections – p.282 Dynamische Erzeugung von Objekten new-Operrator für bekannten Konstruktur, ansonsten newInstance() Methode import java.awt.Rectangle; class SampleNoArg { public static void main(String[] args) { Rectangle r = (Rectangle) createObject("java.awt.Rectangle"); System.out.println(r); } static Object createObject(String className) { Object object = null; try { Class classDefinition = Class.forName(className); object = classDefinition.newInstance(); } catch (InstantiationException e) { System.err.println(e); } catch (IllegalAccessException e) { System.err.println(e); } catch (ClassNotFoundException e) { System.err.println(e); } return object; } } Ausgabe: java.awt.Rectangle[x=0,y=0,width=0,height=0] Info B VL 14: Java Collections/Reflections – p.283 Anmerkung Objekterzeugung auch mit Konstruktor-Argumenten möglich (nutze getConstructor) Info B VL 14: Java Collections/Reflections – p.284 Method Invocation Beispielcode: SampleInvoke Info B VL 14: Java Collections/Reflections – p.285 Bemerkungen (1) Reflections erlauben, Entscheidungen auf die Laufzeit zu verschieben, die man zur Compile-Zeit nicht treffen will oder kann (z.B. Erzeugung von Objekten von zur Compile-Zeit unbekannten Klassen). Dadurch müssen bestimmte Arbeiten, die normalerweise der Compiler leistet, zur Laufzeit erledigt werden (z.B. NoSuchMethodException). Man sollte nicht unbedingt das Reflection API verwenden, wenn sich andere Möglichkeiten ergeben. Beispiel: Anstatt Method-Objekte zu benutzen, ist es meist sinnvoller, ein Interface zu definieren und in der Klasse, die eine bestimmte Methode haben soll, zu implementieren. Info B VL 14: Java Collections/Reflections – p.286 Bemerkungen (2) Bei dynamischer Erzeugung und Nutzung von Objekten (Methoden) können viele Exceptions auftreten. Dynamisches Laden von Klassen kann einfach mit Class realisiert werden: Class c = Class.forName(classname) (siehe z.B. Kapitel “Collections”, Test Alternativen: java.lang.ClassLoader oder java.net.URLClassLoader. Info B VL 14: Java Collections/Reflections – p.287