Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Dynamisches Laden von Klassen

Ähnliche Präsentationen


Präsentation zum Thema: "Dynamisches Laden von Klassen"—  Präsentation transkript:

1 Dynamisches Laden von Klassen
Die Klasse class und die Klassen des Packages java.lang.reflect erlauben Reflection und Introspection. Klassen können zur Laufzeit geladen, untersucht und instanziert werden. Zu den dann erzeugten Objekten können Methoden aufgerufen werden.

2 Die Klasse Class Ein Objekt der Klasse Class beschreibt zur Laufzeit eine Klasse In diesem Objekt sind die statischen Variablen der Klasse angelegt. Zu jeder im java-Programm benutzen Klasse gibt es ein solches Objekt der Klasse Class Ein Objekt der Klasse Class bekommt man von einem Objekt über den Aufruf von getClass(). Die Methode Class.forName(Sting classname) lädt eine Klasse und gibt ein Objekt der Klasse Class zurück.

3 Untersuchen einer Klasse
Die Klasse und das Package java.lang.reflect stellen Methoden und Klassen zur Untersuchung einer Klasse bereit. public Constructor<?>[] getConstructors() public Method[] getDeclaredMethods() public int getModifiers() public Class<?>[] getParameterTypes() . . . So wird es möglich, die Eigenschaften einer Klasse und ihrer Methoden komplett auszulesen.

4 Beispiel zum Auslesen von Informationen Aus einem Objekt Class
Class C=Class.forName(ClassName); if (C.isInterface()) { Out=Modifier.toString(C.getModifiers())+C.getName(); } else Out=Modifier.toString(C.getModifiers()) +" class "+C.getName()+"\n" +"extends "+C.getSuperclass().getName()+"\n"; Class[] Interfaces=C.getInterfaces(); if (Interfaces!=null & Interfaces.length>0) Out+="implements "; for (int i=0; i<Interfaces.length; i++) if (i>0) Out+=", "; Out+=Interfaces[i].getName(); Out+="\n"; Out+="{\n";

5 Field[] Fields=C.getDeclaredFields();
if (Fields.length>0) Out+=" // DataMember\n"; for (int i=0; i<Fields.length;i++) Out+=" "+Fields[i].toString()+";\n"; Constructor[] Constructors=C.getDeclaredConstructors(); if (Constructors.length>0) Out+=" // Constructors\n"; for (int i=0; i<Constructors.length; i++) Out+=" "+Constructors[i].toString()+";\n"; Method[] Methods=C.getDeclaredMethods(); if (Methods.length>0) Out+=" // Methods\n"; for (int i=0; i<Methods.length;i++) Out+=" "+Methods[i].toString()+";\n"; Class[] Classes=C.getClasses(); if (Classes.length>0) Out+=" // Classes / Interfaces\n"; for (int i=0; i<Classes.length;i++) Out+=" "+Classes[i].toString()+";\n"; Out+="}\n"; }

6 Laden einer Klasse Class X=Class.forName(Name); Instanzieren der Klasse Calculate C=(Calculate)(X.newInstance()); Metodenaufruf System.out.println("Y(x)="+C.fVonX(x)); Caclulate ist ein Interface public interface Calculate { public double fVonX(double x); }

7 Beispiel: Ausdrucksberechnung
Ein Programm solle in der Lage sein, beliebige Ausrücke f(x) zu berechnen. Lösungsansatz 1: Ausdrucksberechner mit Verfahren des rekursiven Abstiegs programmieren. Lösungsansatz 2: Verwendung von Jcup/Jlex um einen Interpreter für Ausdrücke generieren zu lassen Lösungsansatz 3: Generieren eines Javaquelltextes einer Klasse mit der Methode fvonx, Übersetzung, Laden, Instanzieren der Klasse und Ausführung der Methode fvonx.

8 Erzeugen des Quelltextes
Class.forName funktioniert für jede zu ladende Klasse nur ein mal. Workaround: fortlaufend nummerierter Dateiname // Hier wird der Name zusammengebaut Name="dcalc"+Count; FileWriter O=new FileWriter(Name+".java"); O.write("class "+Name+" implements Calculate\n"); O.write("{public double fVonX(double x)“); O.write("{return "+Command+";}}"); O.close();

9 Compilieren Process p = Runtime.getRuntime()
.exec("javac "+Name+".java"); System.out.println("Compilation of "+Name+" started"); p.waitFor(); String line; BufferedReader input = new BufferedReader(new InputStreamReader (p.getErrorStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close();

10 Laden und instanzieren
void calculate(double x) { /* Durch Einfuehrung der Funktion calculate verliert das Objekt Class X nach jeder Ausfuehrung sein Leben wird also jedesmal neu angelegt. */ try Class X=Class.forName(Name); Calculate C=(Calculate)(X.newInstance()); System.out.println("Y(x)="+C.fVonX(x)); } catch(Exception e) {System.out.println("Exception " + e);}

11 Der Classloader Jede Klasse wird nur einmalig geladen.
Ausweg, Benutzung eines anderen Classloaders: URLClassLoader Wird mit einem Array von URLs instanziert. Erzeugte Klasse muss in einem Unterverzeichnis liegen, davon URL kreieren, damit URKClassLoader instanzieren, damit Klasse laden - fertig.

12 URL bauen // Get the directory (URL) of the reloadable class
URL[] urls = null; try { // Convert the file object to a URL File dir = new File(System.getProperty("user.dir") +File.separator+"XFX"+File.separator); URL url = dir.toURI().toURL(); System.out.println("URL:"+url); urls = new URL[]{url}; } catch (MalformedURLException e) System.out.println(e);

13 Classsloader instanzieren und rechnen
try { // Create a new class loader with the directory ClassLoader cl = new URLClassLoader(urls); //java.net // Load in the class Class cls = cl.loadClass("dcalc"); // Create a new instance of the new class C = (Calculate)cls.newInstance(); } catch (IllegalAccessException e) {System.out.println(e);} catch (InstantiationException e) {System.out.println(e);} catch (ClassNotFoundException e) {System.out.println(e);} System.out.println("Y="+Command); System.out.println("Y(x)=Y("+x+")="+C.fVonX(x));


Herunterladen ppt "Dynamisches Laden von Klassen"

Ähnliche Präsentationen


Google-Anzeigen