Reflection - inf-swe

Werbung
Reflection
Arthur Zaczek
Nov 2014
Reflection
1
Einleitung
1.1
Definition
Reflection ist das Auslesen von Metainformationen über Klassen, deren Methoden & Eigenschaften
zur Laufzeit.
1.2
•
•
•
•
2
2.1
Anwendungsfälle
Analyse von Programmen (Plugins in der Entwicklungsumgebung)
Plugin-Frameworks
IoC-Pattern (Inversion of control)
etc.
Beispiele
Java
// Class Objekt für my.crm.Person
Class c = new Person().getClass();
// Class Objekt für java.util.HashSet
Set<String> s = new HashSet<String>();
Class c = s.getClass();
// Class Objekt für den Value-Type boolean
Class c = boolean.class;
// Class Objekt für my.crm.Customer
Class c = my.crm.Customer.class;
2.2
CS
// Type Objekt für My.CRM.Person
Type t = new Person.GetType();
// Type Objekt für List<int>()
IList<int> l = new List<int>();
Type t = l.GetType();
// Type Objekt für den Value-Type bool
Type t = typeof(bool);
// Type Objekt für My.CRM.Customer
Type t = typeof(My.CRM.Customer);
2.3
Erklärung
getClass()/GetType() gibt den Typ/Klasse für eine Instanz zurück.
.class/typeof(. . . ) gibt den Typ/Klasse für einen bekannten Typ zurück.
1
Reflection
3
Klassen zur Laufzeit laden
3.1
Java
// Lädt die Klasse „MyLocaleServiceProvider“
Class c = Class.forName("com.duke.MyLocaleServiceProvider");
// Erzeugt ein neues Objekt (Instanz) der Klasse
IService s = (IService)c.newInstance()
3.2
CS
// Läd die Klasse „ServiceProvider“
Type t = Type.GetType(„MyApp.Services.ServiceProvider");
// Läd die Klasse „ServiceProvider“, mit Angabe einer Assembly
Type t2 = Type.GetType(„MyApp.Services.ServiceProvider, MyApp");
// Erzeugt ein neues Objekt (Instanz) der Klasse
IService s = (IService)Activator.CreateInstance(t);
3.3
Anwendungen
Dynamisches Laden von Programmteilen. z.B. können Plugin-Frameworks oder Applikationen
Plugins aufgrund einer Konfiguration laden.
3.4
Beispiel
Ein SMPT Server unterstützt das Speichern von Mails in frei definierbaren Storages. z.B.:
• MemoryMailStore
• DatabaseMailStore
• FileMailStore
3.5
Beispiel
Ein einfacher Web Server auf einem Embedded Device unterstützt das Einbinden von neuen
Funktionen. z.B.:
• Darstellung eines Temeraturverlaufs
• Darstellung des Status der Alarmanlage
• Steuerung der Markisen
4
4.1
Java - laden von Klassen
Arten von Klassen
Java kennt 3 “Arten” von Klassen
2
Reflection
1. Bootstrap classes
2. Extension classes
3. User classes
4.2
Bootstrap classes
Bootstrap sind all jene Klassen, die benötigt werden um die virtuelle Maschine zu initialisieren.
• rt.jar
• jre/lib
Dieser Pfad kann angepasst werden, wird jedoch so gut wie nie benötigt.
4.3
Extension Classes
Sind all jene Klassen, die in jre/lib/ext lokalisiert sind. Es werden nur Klassen aus .jar Dateien
geladen.
4.4
User classes
Sind all jene Klassen, die auf dem Java Plattform aufbauen. Sie werden mit Hilfe des user class
path geladen.
Der user class path ist eine Liste mit
• Verzeichnissen
• .jar Dateien
• .zip Dateien
4.5
.class
Eine .class Datei muss sich in einem Verzeichnis befinden, dass den Package Namen wiederspiegelt.
com.mypackage.MyClass
/myclasses
/myclasses/com/mypackage/MyClass.class
Analoges gilt für die .jar und die .zip Dateien
4.6
CLASSPATH
Der CLASSPATH ist eine Liste von Verzeichssen und .jar Dateien. Als Quelle dienen:
•
•
•
•
Das aktuelle Verzeichnis
die CLASSPATH Umgebungsvariable
-cp bzw. -classpath Command Line Argument
Die .jar Datei, die mit java -jar angegeben wurde
3
Reflection
4.7
JAR-Datei
Eine .jar Datei beinhaltet ein Manifest, in dem auch ein CLASSPATH angegeben werden kann.
4.8
URLClassLoader
Mit dem URLClassLoader können zur Laufzeit Klassen aus .jar Dateien geladen werden.
URL jarURL = new URL("file:///path/to/my.jar");
URL[] classUrls = { jarURL };
URLClassLoader ucl = new URLClassLoader(classUrls);
Class c = ucl.loadClass("MyPackage.MyClass");
4.9
URLClassLoader
Unter Windows muss man den Syntax des Pfades beachten 1 :
For the UNC Windows file path
\\laptop\My Documents\FileSchemeURIs.doc
The corresponding valid file URI in Windows is the following:
file://laptop/My%20Documents/FileSchemeURIs.doc
For the local Windows file path
C:\Documents and Settings\davris\FileSchemeURIs.doc
The corresponding valid file URI in Windows is:
file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc
Das bedeutet, dass unter Windows unter Umständen ein / eingefügt werden muss.
5
C# - laden von Typen
5.1
Assemblies
Typen (Klassen, etc) werden immer in Assemblies kompiliert. Das kann eine .dll oder .exe Datei
sein.
5.2
Referenzen
Assemblies müssen bekannt geben, welche anderen Assemblies benötigt werden - Referenzen.
1 http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
4
Reflection
Figure 1: Referenzen
5
Reflection
5.3
Referenzen
Referenzen können “lose” sein, oder Strong Named.
Bei einer Strong Name Referenz wird die Assembly digital signiert und die Referenz beinhaltet
• den Namen
• eine Versionsnummer
• Hash des Public Keys der Signatur
5.4
Assembly Loader
Assemblies werden in einer genau definierten Reihenfolge gesucht 2 :
1.
2.
3.
4.
5.5
Auswerten der Konifguration
Prüfen von bereits geladenen Assemblies
GAC (Global Assembly Cache)
Suche in der CodeBase
Assembly Loader
Assemblies, die nicht aus dem GAC geladen werden müssen sich im CodeBase Verzeichnis
befinden oder darunter.
CodeBase: Das ist jenes Verzeichnis, in dem die startende Assembly liegt.
“oder darunter”: Nur, wenn es im Config File angegeben wurde (ProbePath)
5.6
LoadFrom
Assemblies können auch händisch geladen werden.
Assembly.LoadFrom("c:\\Sample.Assembly.dll");
Die genannten Einschänkungen gelten dann nicht mehr, es kommen jedoch neue hinzu.
5.7
Referenzen umleiten
Wenn sich z.B. eine Versionsnummer ändert, kann eine Referenz umgeleitet werden, ohne die
Referenzierende Assembly neu zu kompilieren
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
2 http://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.110).aspx
6
Reflection
6
Anotations
6.1
Anwendung
Anotations bzw. Attribute können über Typen/Klassen, Methoden, Felder etc. geschrieben werden,
um Informationen über den Typ anzugeben.
•
•
•
•
6.2
Unit Tests
Plugins: Art des Plugins
XMLSerializer
uvm.
Java
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void helloWorld() throws Exception {
}
6.3
CS
[TestFixture]
public class UEB1 : AbstractTestFixture<IUEB1>
{
[SetUp]
public void SetUp()
{
}
[Test]
public void HelloWorld()
{
}
}
7
7.1
Fields
Java - Fields
// Gibt das Field mit dem Namen „fieldname“ zurück
c.getField("fieldname");
// Gibt alle Fields zurück
7
Reflection
c.getDeclaredFields();
// Gibt die Class des Fields zurück
f.getType();
// Gibt den Namen des Fields zurück
f.getName();
7.2
C# - Fields
// Gibt das Field mit dem Namen „fieldname“ zurück
T.GetField(„fieldname“);
// Gibt alle public Fields zurück
t. GetFields();
// Gibt die Class des Fields zurück
f.FieldType;
// Gibt den Namen des Fields zurück
f.Name;
7.3
Java – r/w von Fields
public class Book {
public long chapters = 0;
public String[] characters = { "Alice", "White Rabbit" };
public static void main(String... args) {
Book book = new Book();
try {
Class<?> c = book.getClass();
Field chap = c.getDeclaredField("chapters");
out.format(fmt, "before", "chapters", book.chapters);
chap.setLong(book, 12);
out.format(fmt, "after", "chapters", chap.getLong(book));
} catch (Exception x) {
x.printStackTrace();
}
}
7.4
C# - r/w von Fields
public class Book
{
public int chapters = 0;
public static void Method(object maybebook)
{
Type t = maybebook.GetType();
FieldInfo f = t.GetField("chapters");
Console.WriteLine("Chapters = " + f.GetValue(maybebook));
f.SetValue(maybebook, 14);
8
Reflection
Console.WriteLine("Chapters = " + ((Book)maybebook).chapters);
}
}
8
Nachteile
8.1
Nachteile
Langsam! Klassen, Felder, Methoden müssen über Strings angesprochen werden.
Typsicherheit! kann nicht garantiert werden.
• Das Objekt muss nicht dem erwarteten Typ entsprechen.
• Fehler werden erst zu Laufzeit erkannt.
• keine Sicherheit durch einen Compiler.
9
Herunterladen