Reflections und final

Status
Nicht offen für weitere Antworten.

SnooP

Top Contributor
Moin... - ich versuche momentan Objekte per Reflection zu kopieren (deep copy) und bin jetzt auf ein ärgerliches kleines Problem gestoßen. Normale selbstgemachte Objekte auch mit Zyklen und Referenzen auf diverse andere Objekte funktioniert ganz wunderbar - primitive Felder werden ebenfalls ohne Probleme kopiert.
Wenn ich jedoch ein Objekt kopieren möchte, welches finale Objekte enthält, wie z.B. nen Integer oder nen String (da passiert irgendwie noch was ganz besonderes...), bekomme ich von der Reflection die Fehlermeldung "Field is final", wenn ich mit field.set(theObject, value); darauf zugreifen will. Logischerweise ist das so, da ja das entsprechende Feld tatsächlich final ist und ein schreibender Zugriff darauf tatsächlich nicht gehen sollte... ich möchte aber ja auch gar nicht weiter darauf zugreifen ;) - nur beim Erstellen des Objekts soll er das tun... wie kopiere ich also möglichst auch diese speziellen Felder mit? Any ideas?

Hat jemand Ahnung von der sun.reflect.ReflectionFactory, bzw. weiß jemand woher die überhaupt kommt? ;) also welche library und woher ich da Infos bekommen könnte, z.B. nen javadoc würde mir schon reichen?
 

byte

Top Contributor
Versuch mal vorher ein:

Code:
field.setAccessible(true);


Edit: sun.reflect.ReflectionFactory findest Du in jre/lib/rt.jar
 

SnooP

Top Contributor
jo - das setAccessible mach ich schon... das bezieht sich aber nur auf private fields. Es scheint so, als ginge es für final-Fields tatsächlich nicht... - allerdings hab ich in der ReflectionFactory ne copyField-Methode gefunden, die evtl. das Feld auf einer anderen Art und Weise kopiert und das Problem umgehen könnte... - hübsch ist das alles nicht, weil ja offenbar die sun.* Klassen nicht wirklich diejenigen sein sollen, die vom "Kunden" benutzt werden sollen... aber ohne die ReflectionFactory kann man numal keine Objekte von Klassen instanzieren, die keinen parameterlosen Konstruktor besitzen... - naja ich bin gespannt wo meine nächsten Grenzen auftauchen werden ;)

edit: wobei mich das javadoc zur set-Methode etwas wundert, wo ja drin steht, dass auch nen zugriff auf final member gehen sollte... mit genau der Anwendungseinschränkung die ich verfolge ;)
 

AlArenal

Top Contributor
SnooP hat gesagt.:
aber ohne die ReflectionFactory kann man numal keine Objekte von Klassen instanzieren, die keinen parameterlosen Konstruktor besitzen...

Weshalb die Doku zu Hibernate beispielsweise auch darauf hinweist, dass zu persistierende POJOs einen solchen Konstruktor besitzen müssen, der aber auch private sein darf. Ist also kein Problem, dass alleine dich betrifft.
 

byte

Top Contributor
SnooP hat gesagt.:
jo - das setAccessible mach ich schon... das bezieht sich aber nur auf private fields.

Naja, nicht wirklich. Die API Doc sagt:

If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this field and this field is non-static.

Aber das ganze klappt nur für blank final Fields. Ist das Feld nicht blank, so wird zwar keine Exception mehr geschmissen, aber das Feld wird trotzdem nicht geändert. ???:L
 

thE_29

Top Contributor
Was bitte bringt es ein blank Field final zu machen?!?!


final Object o = null;

Sehr sinnvoll im Programm :bae:


Nachtrag: Also bei mir geht das final Ändern:


Code:
    testoor or = new testoor();
    
    Field field = or.getClass().getDeclaredField("ing");
    field.setAccessible(true);
    System.out.println(field.get(or));
    field.set(or, new Integer(29));
    System.out.println(field.get(or));    

    field = or.getClass().getDeclaredField("in");
    field.setAccessible(true);
    System.out.println(field.get(or));
    field.setInt(or,129);
    System.out.println(field.get(or));


Code:
public class testoor{
private final Integer ing = new Integer(25);
private final int in = 125;
}


Ausgabe hat gesagt.:
 

byte

Top Contributor
thE_29 hat gesagt.:
Was bitte bringt es ein blank Field final zu machen?!?!

final Object o = null;

Sehr sinnvoll im Programm :bae:

Naja, das bringt in der Tat nix, aber wie wäre es denn so?

Code:
class Foobar {

  final Object o;

  public Foobar(Object o) {
    this.o = o;
  }
}


Ansonsten: Teste es mal mit Objekten anstatt primitiven Datentypen.
 

SnooP

Top Contributor
Hmm... ja - ich habs grad nochmal getestet - die Fehlermeldung war irreführend - es geht nicht bei static final. Wobei ich mich da frage ob die variablen nicht ohnehin schon in meiner Instanz gesetzt sind, da die ja durch die klasse selbst festgelegt werden, wenn ich also vorher rausfinde, ob das entsprechende feld static ist, dann muss ich auch nicht mehr drauf zugreifen! right? ;)
 

thE_29

Top Contributor
Nachtrag:

@byto: doch geht, man musses halt in den Konstruktoren setzen!! (hatte ich vergessen..)
 

byte

Top Contributor
thE_29 hat gesagt.:
Das geht net ;)

final Variablen muss man deklarieren..

Ich krieg jedenfalls nen Fehler!

Dann hast Du nicht richtig getestet. Sicher müssen final Variablen deklariert werden, aber wenn sie blank sind, kann das auch im Konstruktor passieren. Dort ist es dann aber natürlich obligatorisch.
 

SnooP

Top Contributor
Ahja okay - damit scheint es jetzt zu gehen... ich prüfe mit getModifiers() ob sowohl das static, als auch das final bit gesetzt ist und übergehe solche Felder entsprechend.

Das letzte Problem was ich jetzt noch bekomme ist, dass arrays nicht primitiv sind und offensichtlich gesondert behandelt werden wollen ;) - mal gucken, wie ich die jetzt noch am sinnigsten kopiere..
 

SnooP

Top Contributor
Naja... ganz so aber auch nich ;) ... - ich kopiere Arrays jetzt mit System.arraycopy - das funktioniert soweit auch ganz prima... - wobei ich dann nochmal gucken muss, was bei enums passiert *g* - aber das ist eine andere spielwiese ;)
 

Wildcard

Top Contributor
SnooP hat gesagt.:
Naja... ganz so aber auch nich ;) ... - ich kopiere Arrays jetzt mit System.arraycopy - das funktioniert soweit auch ganz prima... - wobei ich dann nochmal gucken muss, was bei enums passiert *g* - aber das ist eine andere spielwiese ;)
Vorsicht! arraycopy funktioniert zwar für primitive Datentypen, aber wenn das Array aus Objekten besteht werden nur die Referenzen kopiert. Das musst du wohl selbst implementieren.
 

SnooP

Top Contributor
Ja da hast du natürlich recht... - da muss ich mir noch was überlegen, im Prinzip müsste ich das Array nur genauso durchiterieren, wie die Felder auch... - schaun ma mal ;)
 

SnooP

Top Contributor
So erledigt ;) ... - der ReflectionCopier ist fertig. Sollte inzwischen alles kopieren können. Klassen die nicht serializable sind, transient Felder, Arrays und mit enums etc. macht es auch keine Probleme.

Wer nen Fehler findet - bitte melden ;) ... wer die sourcen haben will:
bitte hier: http://www-public.tu-bs.de:8080/~y0016815/src/Copier.zip

und viel Spaß damit ;) ... ist auch nen gutes Stück schneller als die Serialisierungs-Methode (die auch mit dabei ist)...

Edit: soo - und jetzt sind auch die überflüssigen imports etc. draußen ;)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Java Reflections Allgemeine Java-Themen 6
T Diskussion - Reflections Allgemeine Java-Themen 21
L Methoden Über Reflections eine Methode mit aufrufen Allgemeine Java-Themen 3
L Operatoren Java Reflections: Alle Methoden einer Klasse aufrufen ohne Exceptions Allgemeine Java-Themen 5
hdi Zu Reflections & Annotations Allgemeine Java-Themen 10
M Typ einer inneren Klasse mit reflections finden Allgemeine Java-Themen 7
T Klasse mit Reflections adden Allgemeine Java-Themen 3
K Reflections Fragen Allgemeine Java-Themen 7
hdi Dynamisches Instantiieren (Reflections) Allgemeine Java-Themen 4
S Reflections (invoke-Methode) Allgemeine Java-Themen 13
G Typ Parameter & Reflections Allgemeine Java-Themen 4
Nils_Langner Wo bin ich gerade? Reflections Allgemeine Java-Themen 3
S Reflections und inherited Fields Allgemeine Java-Themen 4
N Reflections mit Unter- und Oberklasse Allgemeine Java-Themen 2
F Reflections Allgemeine Java-Themen 6
S Auf statische Funktionen mit Java Reflections zugreifen Allgemeine Java-Themen 3
V Wie funktioniert das Schlüsselwort "final" von Java? Allgemeine Java-Themen 19
G final "spammen" + bedeutung Allgemeine Java-Themen 14
J Final Method Allgemeine Java-Themen 9
I Java: public final Werte: Gute oder schlechte Praxis? Allgemeine Java-Themen 6
Neumi5694 Interpreter-Fehler final Eigenschaft während Laufzeit geändert Allgemeine Java-Themen 2
J private static final String variable Allgemeine Java-Themen 8
T Enumeration/Static Final/Bitfield Allgemeine Java-Themen 6
M final vor dem parameter eines Konstruktors Allgemeine Java-Themen 1
D Alle Variablen final setzen ? Allgemeine Java-Themen 26
X Cannot refer to a non-final variable settings inside an inner class defined in a different method Allgemeine Java-Themen 4
G Synchronization on non final field Allgemeine Java-Themen 10
Z Als Final deklarierte Klasse im Array sortieren Allgemeine Java-Themen 2
G Klasse als final -> Laufzeitverbesserung? Allgemeine Java-Themen 4
T Final Methode dennoch überschreiben! Allgemeine Java-Themen 10
W Innere Klasse und final Allgemeine Java-Themen 11
A Als FINAL deklarieren -> sinnvoll? Allgemeine Java-Themen 16
S 2 Fragen allgemeine fragen zu final und interface Allgemeine Java-Themen 13
O does not declare a static final serialVersionUID field of . Allgemeine Java-Themen 6
meez immutable final? Allgemeine Java-Themen 23
S Wave Soundausgabe Java 1.4.2 contra 1.5 Final Allgemeine Java-Themen 27
G final und Variablen Allgemeine Java-Themen 16
B Java 5.0 Final Allgemeine Java-Themen 3
M 1.5 final? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben