Diskussion - Reflections

T

Tashtego

Gast
Hi.

Ich möchte mich näher mit Reflections auseinandersetzen und hier eine Diskussion anstoßen.
- Habt ihr Reflections mal eingesetzt? Produktiv?
- Wie ist eure Meinung dazu?
- Hat sich in letzter Zeit an dem Thema was geändert?
- Welche Links könnt ihr empfehlen?

Alles, was euch zu dem Thema durch den Kopf geht, her damit. Ich bin neugierig.

Gruß
 

LimDul

Top Contributor
Aktiv eingesetzt, eher nein. Indirekt schon sehr häufig (Mockito, Mapstruct, etc.)
Ich war mal in einem Projekt, wo ein Mapping Framework für Druckdaten basierend auf Reflections geschrieben wurde. Das war nicht sinnvoll, weil es schwer wartbar war, man zur Compilezeit keine Fehler sah und der Aufwand das Mapping von Hand zu machen nicht wirklich größer gewesen wäre.

Grundsätzlich ist meine Meinung zu Reflections, und die hat sich auch nicht geändert:
* Toll für ausgereifte, technische Frameworks, die einem Arbeit abnehmen wie eben Mockito oder Mapstruct.
* Im produktiven, fachnahen Code hat das aber nichts zu suchen, weil es ist der Tod von Compile-Zeit Checks, Refactoring & Co. Und lesbar (und damit wartbar) ist es auch selten.
 

Dompteur

Top Contributor
Reflection ist einfach ein Werkzeug, wie viele andere auch. Es ist weder gut noch schlecht. Es hängt von der Aufgabenstellung ab, ob es tauglich ist oder man darauf verzichten soll.

Nur wenn es eine gleichwertige Alternative zu einem Lösungsansatz mit Reflection gibt, ist meist der Ansatz ohne Reflection vorzuziehen.

Ja, ich habe Reflection auch schon in Produktiv-Systemen eingesetzt. Erfahrungsgemäß sind da dann die Fehler-/Exception-Behandlungen ausführlicher.
 
T

Tashtego

Gast
Hm also bisher scheinen das von euch recht wenige zu nutzen. Zu kompliziert? Zu uninteressant? ...
 

thecain

Top Contributor
Steht doch eigtl in den zwei Antworten.

Es gibt selten keine besseren Lösungen, welche ohne Reflections funktionieren.

Oftmals wird Reflection nur eingesetzt, weil das Design nicht gut ist oder jemand besonders "klug" sein will.
 

mihe7

Top Contributor
Hm also bisher scheinen das von euch recht wenige zu nutzen. Zu kompliziert? Zu uninteressant? ...
Ich denke, dass hier fast jeder schon einmal selbst mit Reflection etwas gemacht hat und Deine beiden Fragen würde ich mit "weder noch" beantworten.

Reflection ist weder kompliziert noch uninteressant, jedoch braucht es gute Gründe, sie einzusetzen und das sind eben in erster Linie die von @LimDul genannten Frameworks. Dazu zählen auch Dinge wie JavaBeans, Properties Binding, Validation Framework, Annotation Processing usw. Es gibt also durchaus einige Anwendungsfälle für Reflection.

Hinzu kommt, was genau man unter Reflection versteht: zählt die Klassen-Selbstauskunft via getClass() schon dazu oder der instanceof-Operator? Dann verwendet praktsich jede Implementierung der equals()-Methode schon Reflection...
 

LimDul

Top Contributor
Ich führe meine Antwort noch mal was aus, warum Reflection gefährlich sein kann.

Typsicherheit
Normaler Code:
Java:
String s = obj.getName();
Hier überprüft der Compiler, dass die Typen passen. Ändere ich den Rückgabewert von Name auf meinen neuen DatenTyp NameMitZusatzInfos meckert der Compiler bzw. die IDE exakt die Stellen an, die ich anpassen muss. Nutze ich Reflections bekomme ich erst zur Laufzeit eine Exception.

Refaktoring
Refactor ich Code mit den mitteln der IDE, bleiben Stellen, die den angepassten Code per Reflection nutzen unangepasst. Ich merke es erst wieder zur Laufzeit mit einer Exception.

Verlust von Invarianten
Habe ich beispielsweise in meiner Klasse folgenden Code
Java:
private String name = "";

public void setName(String name) {
  this.name = name == null ? "" : name;
}
Dann kann ich in allen weiteren Methoden in der Klasse sicher sein, dass name niemals null ist. Setze ich das mittels Reflections auf null, gilt die Annahme nicht mehr. Mir fliegt also irgendwo eine NPE. Und wenn ich dann versuche zu analysieren wo die herkommt, ist das extrem aufwendig, weil alle IDE Bordmittel wie Call Hierachie und Co nicht greifen. Und nicht immer kann man mit einem Debugger ran.

Natürlich treffen nicht alle diese Nachteile immer zu und bei geschickter Programmierung kann man die minimieren. Aber ganz weg bekommt man sie nie.

Daher ist eine Variante ohne Reflections in den meisten Fällen immer der bessere weg.

Ich formuliere die Frage mal um: Warum willst du Reflections nutzen?
 
T

Tashtego

Gast
Ich spiele gerade damit herum, ein Tool zu schreiben, was einen serialisierten Java-Objekt-Graph in einer GUI anzeigt. Und zwar von beliebigen externen Jar-Files, deren Inhalt ich erstmal nicht kenne. Daher bin ich gerade bei Reflections gelandet.
Zum anderen arbeite ich mich näher in das Thema ein, um eventuell nen kleine Vortrag dazu abzuhalten. Und da bin ich dann auch neugierig auf die Meinung in der Community, die bisherigen Erfahrungen etc. Ich bin also für jede Antwort hier dankbar :)

Was ich selbst noch nicht genau weiß, ist z.B. wie es aktuell mit Änderungen / Neuerungen in dem Bereich aussieht, da es Reflections an sich schon ewig gibt. Und ich hab mal glaub was gelesen von jars, die mit security irgendwie geschützt sind und damit der Code vor Reflections geschützt ist. Aber ich bin da noch nicht so weit mit meiner Recherche. Ich möchte das Thema halt einmal komplett durchgekaut und dann abgehakt haben für mich :) Und wer will, kann sich hier gern beteiligen.
 

White_Fox

Top Contributor
Reflection ist einfach ein Werkzeug, wie viele andere auch. Es ist weder gut noch schlecht. Es hängt von der Aufgabenstellung ab, ob es tauglich ist oder man darauf verzichten soll.
Exakt, so sehe ich das auch. Manche Werkzeuge sind für die einen Probleme besser geeignet, für andere weniger.

Reflexion hab ich einmal zum Debuggen eingesetzt, und gerade setze ich es wieder ein um Informationen über ein Objekt zu sammeln um es zu speichern (Vermeidung von Problemen mit Zirkelreferenzen).
 

mihe7

Top Contributor
Und ich hab mal glaub was gelesen von jars, die mit security irgendwie geschützt sind und damit der Code vor Reflections geschützt ist. Aber ich bin da noch nicht so weit mit meiner Recherche.
Jein. Wenn Du mit Modulen arbeitest, werden die Pakete gekapselt, so dass Du zunächst keinen Zugriff darauf hast. Du kannst Pakete exportieren (Abhängigkeiten zur Kompilierzeit ermöglichen) oder aber auch für Reflection öffnen.
 

JuKu

Top Contributor
- Habt ihr Reflections mal eingesetzt? Produktiv?

Ja, klar!
Reflection kommt heutzutage viel öfter zum Einsatz, als du denkst.

- Wie ist eure Meinung dazu?

Kann Java kaputt machen, muss es aber nicht.
Ich halte es für ziemlich sinnvoll, wenn man Sachen "injection" will (Stichwort: Dependency Injection).

- Hat sich in letzter Zeit an dem Thema was geändert?

Reflection gibt es seit Java 8, das Thema ist also schon so uralt, dass sich da jetzt kaum noch groß was ändern wird.

- Welche Links könnt ihr empfehlen?

Diesen Link:
https://www.journaldev.com/1789/java-reflection-example-tutorial
 

httpdigest

Top Contributor
aber die meisten Klassen / Methoden stammen aus Java 8, z.B. zur Runtime auf Parameter zuzugreifen:
https://openjdk.java.net/jeps/118
Naja, auch nicht ganz korrekt. "Die meisten" Neuerungen gab es mit Java 1.1 (nur "Introspection" möglich), danach folgte noch einiges mit Java 1.2 (Änderungen per Reflection zur Laufzeit vornehmen, z.B. Felder setzen), noch ein bisschen in 1.4, 5 und 6 und ganz ganz gaaaaanz wenig kam mit Java 8 (nämlich nur Parameternamen reflexiv abfragen). Man kann die ab Java 7 hinzugekommenen MethodHandles (bzw. das ganze java.lang.invoke Package) jetzt auch noch zu Reflection hinzurechnen (obwohl es technisch gesehen nicht zur Java Core Reflection API gehört), da es sehr ähnliche Funktionalität bietet wie java.lang.reflect, nur sehr viel performanter ist, da Accessibility-Checks nicht mehr bei jedem Aufruf gemacht werden.
 
T

Tashtego

Gast
Naja, auch nicht ganz korrekt. "Die meisten" Neuerungen gab es mit Java 1.1 (nur "Introspection" möglich), danach folgte noch einiges mit Java 1.2 (Änderungen per Reflection zur Laufzeit vornehmen, z.B. Felder setzen), noch ein bisschen in 1.4, 5 und 6 und ganz ganz gaaaaanz wenig kam mit Java 8 (nämlich nur Parameternamen reflexiv abfragen). Man kann die ab Java 7 hinzugekommenen MethodHandles (bzw. das ganze java.lang.invoke Package) jetzt auch noch zu Reflection hinzurechnen (obwohl es technisch gesehen nicht zur Java Core Reflection API gehört), da es sehr ähnliche Funktionalität bietet wie java.lang.reflect, nur sehr viel performanter ist, da Accessibility-Checks nicht mehr bei jedem Aufruf gemacht werden.

danke dir!
 
T

Tashtego

Gast
Es gibt den Aufruf instanceof und das Casten (Person)obj... Ruft dieser Cast intern die Class.cast() Methode auf? Ich gehe davon aus, das beides ist Bestandteil von Reflections?
 

httpdigest

Top Contributor
Sowohl instanceof (und die gleichnamige Bytecode-Instruktion) als auch das Casten (entweder per Java-Syntax oder per Class.cast() Methodenaufruf - letztlich ja die checkcast Bytecode Instruktion) würde ich nicht als Bestandteil von der Reflection API zählen.
 

mihe7

Top Contributor
Wobei ich mich schon frage, ob man "instanceof" (und getClass()) nicht als Reflection bezeichnen müsste, schließlich wird zur Laufzeit Auskunft über die Datentypen erteilt. In C++ (zumindest in frühen Versionen) gab es derlei Möglichkeiten nicht.
 
T

Tashtego

Gast
Naja was bytecode instruktionen angeht, bin ich bisher ja total blank! (https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings) wow... ich weiß aber daß das Class.cast(obj) wohl dasselbe macht wie der Cast mittels (Person)obj. Was aber nicht zwingend AUSSAGT, daß das Reflection Inhalt ist... Die Klasse java.lang.Class ist aber ja nicht im reflection package, gehört aber trotzdem zu Reflections dazu, wenn man getClass() nutzt etc.
 
T

Tashtego

Gast
Beispiel:

Class<? extends Persion> clazz = Person.class;
Object person2 = new Person();
Person person3 = clazz.cast(person2);
 

Ähnliche Java Themen

Neue Themen


Oben