Soru Verilen nesne içindeki mevcut ek açıklamaları tespit etmek, bir kurucuya aktarıldı


Sorum şu: belirli bir kullanıcı sınıfı / nesnesi için bir java ek açıklığının (ve doğru yerde) bulunup bulunmadığını nasıl anlarım.

"Problem" in detayları

İki java dersim olduğunu söyleyelim:

public class Line {
   private List<Cell> cells;

   public Line(Object... annotatedObjects) {
     // check if annotations @Line and @Cell are present in annotatedObjects.
   }

   // getter/setter for cells.
}

public class Cell {
   // some members
   // some methods
}

Bir Satır nesnesi Hücreler tutar.

Aynı zamanda iki ek notum var:

public @interface Line {
  // some stuff here
}

public @interface Cell {
  // some stuff here
}

Ayrıca belirttiğim @Line ve @Cell ek açıklamalarını içeren bir grup kullanıcı sınıfı (bu örnek için iki tane yapacağım) var:

@Line(name="pqr", schema="three")
public class AUserClass {
   @Cell
   private String aString;
}

@Line(name="xyz", schema="four")
public class AnotherUserClass {
   @Cell(name="birthday")
   private Date aDate;
}

Sorun: Yeni bir Satır nesnesini başlattığımda, kullanıcı sınıflarını / nesnelerini Satır yapıcısına iletebilmek istiyorum. Satır kurucu, geçirilen kullanıcı sınıflarının / nesnelerinin işlenebilecek geçerli sınıflar olup olmadığını öğrenir. Sadece sahip kullanıcı sınıfları @Line sınıf için ek açıklama ve en az bir @Cell üyeleri için ek açıklama, Line nesnesinin yapıcısına iletilebilen geçerli nesnelerdir. Diğer tüm geçirilen nesneler geçersiz. Geçerli bir kullanıcı nesnesinin geçtiği an, şu şekilde etiketlenmiş tüm mevcut üyeler @Cell Bu nesnede Hücre nesnelerine dönüştürülür ve hücre listesine eklenir.

Sorularım:

  1. Bu nesne / sınıftaki açıklamaları çalışma zamanında algılamak mümkündür ve yalnızca bu nesnenin geçirilmiş olması için (sınıf yolunda ek açıklamalar için taramak istemiyorum!)?
  2. veri türünü tespit etmek mümkün mü @Cell etiketli üyeler? Bu, Hücre sınıfı tüm veri türlerini kabul etmediği için gereklidir.
  3. asıl üye ismini (java dosyasında belirtilen) almak mümkün olur, böylece kullanıcının üye adını belirtmesi gerekmez. Kullanıcının yazabilmesini istiyorum @Cell (isimsiz) ve @Cell(name="aName")ve sadece @Cell belirtilir, bunun yerine üye adı kullanılır. Bu bilginin yansıma kullanılarak çalışma zamanında mevcut olup olmadığı hakkında hiçbir fikrim yok.
  4. Ek açıklamaların doğru yerde olup olmadığı nasıl tespit edilir? Kod böyle etiketlenirse, nesne göz ardı edilmemelidir (veya bir istisna atılır)?
    @Cell // oh oh, that's no good :(
    public class WrongClass {
    // some members
    }

25
2017-12-06 09:51


Menşei




Cevaplar:


Öncelikle notlarınızda tutma politikanız olmalı, böylece bunları yansımayla okuyabilirsiniz.

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  public static @interface Line {

  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public static @interface Cell {

  }

İkincisi, sınıfın Satır açıklamasına sahip olup olmadığını sınamanız gerekir. isAnnotationPresent(annotationClass). Bu yönteme java.lang.Class ve bir java.lang.reflect.Field.

NOT: Özel olan alanları almanız gerekiyor class.getDeclaredField(fieldName).

3. Bir açıklamanın, bir özellikAdı temel alınarak varsayılan bir değere sahip olabileceğini sanmıyorum, ancak varsayılan olarak bir ad sağlayarak adınızı isteğe bağlı yapabilirsiniz String name() default DEFAULT ve alanlar arasında yineleme yaparken bu değeri kontrol edin ve ya kaydedilen değeri kullanın. name() ya da propertyName


34
2017-12-06 10:03



Kendi sorularımın bazılarını cevaplamak: 1. yukarıya bakın; 2. Alanın veri türünü bulmak için java.lang.reflect.Field yöntemlerini kullanın: getName () ve getType (); 4. yukarıya bakın; 5. Java 4'teki Düşünme ve Eylemdeki Java yansıması'na bakın (yanıtlar için iyi kaynaklar). 3. hala cevapsız. - user504342
@ user504343, bu yüzden @ Cell.name 'nin takıldığı özellik adına varsayılan olmasını mı istiyorsunuz? - Liviu T.
Evet bu doğru. Alanda @Cell varsa, Cell.name için alan adını seçin. Alanda @Cell (name = "hello") varsa, bunu Cell.name olarak seçin. Eğer @Cell (name = "") alan adını da seçerse. - user504342


S.1: Bu nesne / sınıftaki ek açıklamaları çalışma zamanında algılamak mümkündür ve sadece bu nesneye geçti (sınıf yolunda ek açıklamalar için taramak istemiyorum!)?

Evet kullanarak çok iyi mümkün isAnnotationPresent 

@Deprecated
public class AnnotationDetection {

    public static void main(String[] args) {
        AnnotationDetection annotationDetection = new AnnotationDetection();
        System.out.println(annotationDetection.getClass().isAnnotationPresent(Deprecated.class));
    }
}

Not tutmak için kapsam dahil edildi Runtimesadece mevcut olacak


18
2017-12-06 10:01



Nasıl açıklar mısın? - Don
@Don this.getClass().isAnnotationPresent(SomeAnnotation.class) - Jigar Joshi
, her zaman yanlış olacaktır. GetClass, Class nesnesinin örneğini verdiğinden ve amaçlanan açıklama içermiyor. - Don
Bu sınıfın belirli bir ek açıklama olup olmadığını kontrol etmek istediğiniz sınıfın sınıf örneğini almanız gerekiyor, javadoc'u kontrol edin - Jigar Joshi
Bunu kontrol edin, çalışma zamanında bunu yapmak mümkün değil gibi görünüyor. - Don