Farklı saklama politikaları ek açıklamalarımı nasıl etkiler?


175

Herkes net bir şekilde arasındaki pratik farklılıkları açıklayabilir java.lang.annotation.RetentionPolicysabitler SOURCE, CLASSve RUNTIME?

Ayrıca, "ek açıklama tutma" ifadesinin ne anlama geldiğinden tam olarak emin değilim.



evet zaten okudum ama pratikte nasıl çalıştığını anlamıyorum. Aslında ben 'bu ifade' denerseniz: "" "" Ek açıklamalar derleyici tarafından sınıf dosyasına kaydedilecek ancak çalışma zamanında VM tarafından tutulması gerekmez. "" "ve daha sonra ayrıştırma sınıfını
açtığım

2
Ardından, kod çözücünüz ek açıklamaları desteklemiyor gibi görünüyor. jd-gui iyi çalışıyor.
musiKk

Teşekkürler sorun benim decompiler dj ve jad oldu ... jd-gui bana göster !!
xdevel2000

Yanıtlar:


210
  • RetentionPolicy.SOURCE: Derleme sırasında atın. Derleme tamamlandıktan sonra bu ek açıklamalar bir anlam ifade etmez, bu nedenle bayt koduna yazılmaz.
    Örnek: @Override,@SuppressWarnings

  • RetentionPolicy.CLASS: Sınıf yükü sırasında atın. Bayt kodu düzeyinde son işlem yaparken kullanışlıdır. Biraz şaşırtıcı bir şekilde, bu varsayılan değerdir.

  • RetentionPolicy.RUNTIME: Atmayın. Ek açıklama çalışma zamanında yansıtılmak üzere hazır olmalıdır. Misal:@Deprecated

Kaynak: Eski URL artık öldü hunter_meta ve yerine hunter-meta-2-098036 yerleştirildi . Bu bile düşerse, sayfanın görüntüsünü yüklüyorum.

Görüntü (Sağ Tıklayın ve 'Görüntüyü Yeni Sekmede / Pencerede Aç' ı seçin) Oracle web sitesinin ekran görüntüsü


1
alıntı için teşekkürler, burada en ilginç kullanım örneğiRetentionPolicy.CLASS
Max

2
RetentionPolicy.class'ın neden ilginç / şaşırtıcı bir şekilde varsayılan olduğunu açıklayabilir misiniz?
sudocoder

1
@sudocoder - Şu bağlantılara bakın: stackoverflow.com/a/5971247/373861 ve stackoverflow.com/a/3849602/373861 . Bayt kodu enstrümantasyonu için bu özel politikanın gerekli olduğuna inanıyorum. Ben hiç kullanmadım.
Favonius

Sonunda diyor Bu dizinin bir sonraki makalesinde, Java'nın yansıtma özelliklerinin çalışma zamanında ek açıklamaları keşfetmenize yardımcı olmak için nasıl geliştirildiğini ve Ek Açıklama İşleme Aracı "uygun" ifadesinin oluşturma sırasında ek açıklamaları nasıl kullanmanıza izin verdiğini göstereceğim. , bu makale nerede?
Sushant

@Sushant: Nerede olduğundan emin değilim :). Kullanımdan aptkaldırılmış olsa da bu docs.oracle.com/javase/7/docs/technotes/guides/apt/… adresine bakın . Yansımayı kullanarak ek açıklama keşfetmek için internette birden fazla öğretici vardır. Sen içine bakarak başlayabilirsiniz java.lang.Class::getAnno*ve benzer yöntemlerle java.lang.reflect.Methodve java.lang.reflect.Field.
Favonius

57

Sınıf ayrışması hakkındaki yorumlarınıza göre, bunun nasıl çalışması gerektiğini düşünüyorum:

  • RetentionPolicy.SOURCE: Ayrıştırılmış sınıfta görünmeyecek

  • RetentionPolicy.CLASS: Ayrıştırılmış sınıfta görünür, ancak çalışma zamanında yansıma ile denetlenemez. getAnnotations()

  • RetentionPolicy.RUNTIME: Ayrıştırılmış sınıfta görünür ve çalışma zamanında yansıma ile denetlenebilir getAnnotations()


Evet ben de öyle düşündüm ama ayrıştırılmış sınıfta hiçbir şey mevcut !!! ve bu yüzden kafam karıştı ... Sınıf dosyasını
javap

javap o zaman nereye konur bir şey döndürür?
10:07

1
RetentionPolicy.CLASS herhangi bir kullanım durumu?
Rahul

20

Minimum çalıştırılabilir örnek

Dil seviyesi :

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}

@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}

@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}

public static void main(String[] args) {
    @RetentionSource
    class B {}
    assert B.class.getAnnotations().length == 0;

    @RetentionClass
    class C {}
    assert C.class.getAnnotations().length == 0;

    @RetentionRuntime
    class D {}
    assert D.class.getAnnotations().length == 1;
}

Bytecode seviyesi : kullanarak javapbunu gözlemlemek Retention.CLASSaçıklamalı sınıf bir alır RuntimeInvisible class özelliği:

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()

ise Retention.RUNTIMEek açıklama bir alır RuntimeVisible class özelliği:

#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()

ve Runtime.SOURCEek açıklama ek açıklama .classalmaz.

GitHub'da oynamanız için örnekler .


Peki herhangi bir fikir Runtime.SOURCE ve Runtime.CLASS kullanımı nedir?
Praveen Kamath

@PraveenKamath Yararlı oldukları herhangi bir örnek bilmiyorum. Büyük olasılıkla, çoğu geliştiricinin asla yapmadığı daha düşük düzeyli JVM şeyler yapıyorsanız gerçekleşir. Onlar için bir başvuru bulursanız bana bildirin.
Ciro Santilli 法轮功 18 病 六四 事件 法轮功

5

Saklama Politikası: Saklama politikası, ek açıklamanın hangi noktada atılacağını belirler. Java'nın yerleşik ek açıklamaları kullanılarak belirtilir: @Retention[Hakkında]

1.SOURCE: annotation retained only in the source file and is discarded
          during compilation.
2.CLASS: annotation stored in the .class file during compilation,
         not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.

0
  • SINIF : Ek açıklamalar derleyici tarafından sınıf dosyasına kaydedilmelidir, ancak çalışma zamanında VM tarafından saklanması gerekmez.
  • ÇALIŞMA SÜRESİ : Ek açıklamalar derleyici tarafından sınıf dosyasına kaydedilmeli ve çalışma zamanında VM tarafından saklanmalıdır, böylece yansıtıcı olarak okunabilir.
  • KAYNAK : Ek açıklamalar derleyici tarafından atılmalıdır.

Oracle Doc

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.