Değişim statik son alan Java kullanarak yansıma özel
Ne yazık ki, çalışma zamanında değişmesi gereken private static final
alanı olan bir sınıf var.
Bu hata alıyorum yansıma kullanarak: java.lang.IllegalAccessException: Can not set static final boolean field
Değeri değiştirmek için herhangi bir yolu var mı?
Field hack = WarpTransform2D.class.getDeclaredField("USE_HACK");
hack.setAccessible(true);
hack.set(null, true);
CEVAP
Varsayarak hayır SecurityManager
önleme senden bunu kullanabilirsiniz setAccessible
vakit private
ve sıfırlama değiştirici kurtulmak final
ve aslında değiştirmek private static final
alan.
İşte size bir örnek:
import java.lang.reflect.*;
public class EverythingIsTrue {
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(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}
}
SecurityException
atılan hiçbir varsayarsak, yukarıdaki kod "Everything is true"
yazdırır.
Aslında burada ne yapmış aşağıdaki gibidir:
main
true
false
başvuru türü için autoboxedboolean
ilkel değerlerBoolean
"sabit"Boolean.TRUE
Boolean.FALSE
- Yansıma
Boolean
Boolean.TRUE
tarafından sevk başvurmak içinpublic static final Boolean.FALSE
değiştirmek için kullanılır false
Boolean.FALSE
autoboxed. daha sonra sonuç olarak, birBoolean.TRUE
tarafından referans olarakBoolean
ifade eder- Şimdi
"false"
herşey"true"
İlgili sorular
- Using reflection to change
static final File.separatorChar
for unit testing - How to limit setAccessible to only “legitimate” uses?
Integer
'In önbelleği,String
, vb . bir mutasyona karıştırmasını örnekleri vardır
Uyarılar
Çok dikkatli böyle bir şey yaptığınızda alınmalıdır. SecurityManager
bir hediye olabilir çünkü işe yaramayabilir, ama eğer doğru değilse, kullanım tarzına bağlı olarak bu değilse bile, olabilir veya çalışmayabilir.
JLS 17.5.3 Subsequent Modification of Final Fields
Bazı durumlarda, kaldırma gibi, sistem inşaat sonrası nesne
final
alanları değiştirmek gerekir.final
yansıma alanları ve diğer uygulama bağımlı yollarla değiştirilebilir. Bu makul semantiği var sadece deseni olan bir nesne oluşturulur ve bu nesnefinal
güncellenir. Nesne için başka bir iş parçacığı görünür yapılmamalıdır, ne definal
alanları nesneninfinal
alanları için tüm güncellemeler tamamlanana kadar okumak gerekir. Donuyor birfinal
alanı oluşur hem de sonuna kurucusu olanfinal
alan ayarlayın ve hemen sonra her değişiklikfinal
alan üzerinden yansıması ya da diğer özel bir mekanizma.O zaman bile, komplikasyonları vardır. Eğer bir
final
alan başlatılmış bir derleme zamanı sabiti alanında bildirimi değişiklikleri içinfinal
alan olmayabilir gözlenen, yana kullanır ofinal
saha değiştirilir derleme zamanında ile derleme zamanı sabiti.Başka bir sorun belirtimi
final
alanların agresif optimizasyon sağlar. Bir iş parçacığı içinde, kurucu gerçekleşecek son bir alanın bu değişikliklerfinal
alan okur yeniden düzenlemek için izin verilir.
Ayrıca Bkz
- JLS 15.28 Constant Expression
- Bu teknik bir ilkel bir kez derleme "yeni" değeri gözlemlenebilir olmayabilir . sabit ve böylece inlineable çünkü 43 ** ile çalışıyor, pek olası değil
Ek: bit manipülasyon
Aslında
field.getModifiers() & ~Modifier.FINAL
kapatır bit field.getModifiers()
45 *karşılık. &
-tamamlayıcı bit bit-ve, ve ~
.
C özel salt okunur bir alan değiştireb...
Nasıl Java özel bir alan okuyabilirim?...
Kullanarak Özel Statik Yöntemler avant...
Statik bir yöntem kullanarak yansıma ç...
Yansıma Java: Nasıl bir Yöntem statik ...