SORU
21 Temmuz 2010, ÇARŞAMBA


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
21 Temmuz 2010, ÇARŞAMBA


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 autoboxed boolean ilkel değerler Boolean "sabit" Boolean.TRUE Boolean.FALSE
  • Yansıma Boolean Boolean.TRUE tarafından sevk başvurmak için public static final Boolean.FALSE değiştirmek için kullanılır
  • false Boolean.FALSE autoboxed. daha sonra sonuç olarak, bir Boolean.TRUE tarafından referans olarak Boolean ifade eder
  • Şimdi "false" herşey "true"

İlgili sorular


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 nesne final güncellenir. Nesne için başka bir iş parçacığı görünür yapılmamalıdır, ne de final alanları nesnenin final alanları için tüm güncellemeler tamamlanana kadar okumak gerekir. Donuyor bir final alanı oluşur hem de sonuna kurucusu olan final alan ayarlayın ve hemen sonra her değişiklik final 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çin final alan olmayabilir gözlenen, yana kullanır o final 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şiklikler final 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 ~.

Ayrıca Bkz

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Android Central

    Android Cent

    13 Kasım 2008
  • PlugResearch

    PlugResearch

    22 Mart 2006
  • Truc Minh

    Truc Minh

    23 Ocak 2011