Info B VL 14: Java
Collections/Reflections
Objektorientiere Programmierung in Java 2003
Ute Schmid (Vorlesung) Elmar Ludwig ( ¨Ubung)
FB Mathematik/Informatik, Universit¨at Osnabr¨uck
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
‘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!
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.
Struktur der Collection Klassen
C C
C C C
S S
S S S
C
C S
S java.lang
Object AbstractCollection AbstractList AbstractSequentialList LinkedList ArrayList
Vector HashSet TreeSet AbstractSet
Stack
Collection
<<interface>>
List
Set SortedSet
<<interface>>
<<interface>> <<interface>>
java.util
AbstractMap HashMap
TreeMap
<<interface>>
Map SortedMap
<<interface>>
Iterator ListIterator Comparator
<<interface>> <<interface>>
<<interface>>
(S: implements Serializable, C: implements Clonable)
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
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.
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;
}
‘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 }
‘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 }
‘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 }
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 In- formationen: Klassenfelder, implementiertes Interface, Kon- struktoren, Methoden-Information
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;
} }
Anmerkung
Objekterzeugung auch mit Konstruktor-Argumenten möglich (nutze getConstructor)
Method Invocation
Beispielcode: SampleInvoke
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.
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.