Nicht ändern kann static final-Feld mit Hilfe der java reflection?
Ich vor kurzem gestolpert Ändern private static final-Feld mit Hilfe der Java reflection und getestet polygenelubricants' EverythingIsTrue
Klasse, funktioniert einwandfrei, System.out.format("Everything is %s", false);
Drucke Everything is true
in der Tat. Aber wenn ich den code wie
public class EverythingIsTrue {
public static final boolean FALSE = false;
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String[] args) throws Exception {
setFinalStatic(EverythingIsTrue.class.getField("FALSE"), true);
System.out.format("Everything is %s", FALSE);
}
}
druckt es
Everything is false
Weiß jemand warum? Tut setFinalStatic eigentlich funktionieren oder nicht?
InformationsquelleAutor Evgeniy Dorofeev | 2012-12-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beim Zugriff auf primitive static final Felder, die Java-compiler davon aus, dass der Wert ist eine Konstante und inline-Wert anstelle der Generierung von code für den Zugriff auf das Feld. Dies bedeutet, dass der compiler ersetzen mit dem Verweis auf die
FALSE
- Feld mit dem Wertfalse
. Wenn Sie verwenden Sie reflektion, um Zugriff auf das Feld, werden Sie sehen, dass der Wert des Feldes tatsächlich geändert hat.Dies funktioniert nicht für nicht-primitive Felder, die als Wert eine Referenz auf ein Objekt kann nicht inlined zur compile-Zeit.
es sieht aus wie es werden unendlich mehr Worte selbst 😉
Ich gelöscht meine Antwort wie deine hatte, wurde akzeptiert und war mir nicht irgendwelches Wert - nur die Kürze! 😉
Eigentlich ist es nicht
public static final boolean TRUE = "".isEmpty();
werden NICHT inlined, obwohl es offensichtlich ist Ihnen und mir, dass der Wert immertrue
. Der Grund ist, dass, der Ausdruck ist nicht ein "konstanter Ausdruck" gemäß der JLS.InformationsquelleAutor Jan B
Können Sie vermeiden, compiler inlining, indem Sie den Wert ein Ergebnis des Aufrufs einer Methode, sogar ein dummy.
Drucke
static <T> T placeHolder() { return null; }
frühere version war besser lesbar.
Es ist die Ausgabe der Konsole, so sollte es nicht formatiert werden, als ob es source-code.
Ich denke, die Idee war das highlight der
true
undfalse
machen den Unterschied deutlich.InformationsquelleAutor Peter Lawrey