सवाल क्या जावा में एनोटेशन के मूल्य को पढ़ना संभव है?


यह मेरा कोड है:

@Column(columnName="firstname")


private String firstName;

 @Column(columnName="lastname")
 private String lastName;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

क्या मेरे एनोटेशन @ कॉलम के मूल्य को पढ़ना संभव है (आम नाम= "xyz123") एक और कक्षा में?


76
2017-11-28 13:16


मूल




जवाब:


हां, अगर आपके कॉलम एनोटेशन में रनटाइम प्रतिधारण है

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

आप ऐसा कुछ कर सकते हैं

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}

90
2017-11-28 13:27



मुझे आपका समाधान पसंद है। हम इसे MyClass की बजाय अधिक सामान्य बना सकते हैं, मैं टी जैसे (फ़ील्ड एफ: T.class.getFields ()) {कॉलम कॉलम = f.getAnotation (Column.class) का उपयोग करना चाहता हूं; अगर (कॉलम! = शून्य) System.out.println (column.columnName ()); } - ATHER
ठीक ठीक! मैं इसे भी समझने के लिए संघर्ष कर रहा हूं। क्या होगा यदि मैं एक एनोटेशन प्रोसेसर रखना चाहता हूं जिसे क्लास नाम के साथ स्पष्ट रूप से प्रदान करने की आवश्यकता नहीं है? इसे संदर्भ से चुनने के लिए बनाया जा सकता है; 'इस'?? - 5122014009
मुझे यकीन नहीं है कि मैं समझता हूं कि आप दोनों को क्या चाहिए। कृपया एक पूर्ण उदाहरण के साथ एक नए प्रश्न के रूप में पूछें। यदि आप चाहें तो आप इसे यहां लिंक कर सकते हैं। - Cephalopod
उपयोग Myclass.class.getDeclaredFields() निजी क्षेत्रों को पाने के लिए - q0re
यह मेरे लिए काम किया। धन्यवाद। मैं सुपरक्लास निजी फ़ील्ड की तलाश में था इसलिए मैंने clsName.getSuperclass () का उपयोग किया। GetDeclaredFields () - Shashank


निश्चित रूप से यह है। यहां एक नमूना एनोटेशन है:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    String testText();
}

और नमूना एनोटेटेड विधि:

class TestClass {

    @TestAnnotation(testText="zyx")
    public void doSomething() {}
}

और किसी अन्य वर्ग में एक नमूना विधि जो testText के मान को मुद्रित करती है:

Method[] methods = TestClass.class.getMethods();
for (Method m : methods) {
    if (m.isAnnotationPresent(TestAnnotation.class)) {
        TestAnnotation ta = m.getAnnotation(TestAnnotation.class);
        System.out.println(ta.testText());
    }
}

आपके जैसे फील्ड एनोटेशन के लिए बहुत अलग नहीं है।

Cheerz!


67
2017-11-28 13:30



वाह बहुत अच्छा! सरल उदाहरण के लिए धन्यवाद। स्पष्ट रूप से चरण-दर-चरण प्रक्रिया को स्पष्ट करता है। - Dan Torrey
एनोटेशन के मूल्यों को पुनः प्राप्त करने की प्रक्रिया की वास्तव में अच्छी व्याख्या। - Arlind


मैंने कभी ऐसा नहीं किया है, लेकिन ऐसा लगता है प्रतिबिंब यह प्रदान करता है Field है एक AnnotatedElement और इसलिए यह है getAnnotationयह पन्ना एक उदाहरण है (नीचे कॉपी); अगर आप एनोटेशन की कक्षा जानते हैं और एनोटेशन पॉलिसी रनटाइम पर एनोटेशन को बरकरार रखती है तो काफी सरल है। स्वाभाविक रूप से यदि प्रतिधारण नीति रनटाइम पर एनोटेशन नहीं रखती है, तो आप इसे रनटाइम पर क्वेरी करने में सक्षम नहीं होंगे।

एक उत्तर जिसे हटा दिया गया है (?) ने एक उपयोगी लिंक प्रदान किया है एक एनोटेशन ट्यूटोरियल कि आप सहायक पा सकते हैं; मैंने यहां लिंक कॉपी किया है ताकि लोग इसका इस्तेमाल कर सकें।

से उदाहरण यह पन्ना:

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

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
  String str();

  int val();
}

class Meta {
  @MyAnno(str = "Two Parameters", val = 19)
  public static void myMeth(String str, int i) {
    Meta ob = new Meta();

    try {
      Class c = ob.getClass();

      Method m = c.getMethod("myMeth", String.class, int.class);

      MyAnno anno = m.getAnnotation(MyAnno.class);

      System.out.println(anno.str() + " " + anno.val());
    } catch (NoSuchMethodException exc) {
      System.out.println("Method Not Found.");
    }
  }

  public static void main(String args[]) {
    myMeth("test", 10);
  }
}

19
2017-11-28 13:23





हालांकि अब तक दिए गए सभी उत्तर पूरी तरह मान्य हैं, लेकिन किसी को भी ध्यान में रखना चाहिए गूगल प्रतिबिंब पुस्तकालय एनोटेशन स्कैनिंग के लिए एक और सामान्य और आसान दृष्टिकोण के लिए, उदा।

 Reflections reflections = new Reflections("my.project.prefix");

 Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);

4
2018-02-05 08:34





@ सेफलोपॉड के जवाब के बारे में बताते हुए, यदि आप किसी सूची में सभी कॉलम नाम चाहते थे तो आप इस ऑनलाइनर का उपयोग कर सकते हैं:

List<String> columns = 
        Arrays.asList(MyClass.class.getFields())
              .stream()
              .filter(f -> f.getAnnotation(Column.class)!=null)
              .map(f -> f.getAnnotation(Column.class).columnName())
              .collect(Collectors.toList());

3
2018-04-18 20:00



ऑब्जेक्ट्सऑन नल जावा 8 को पूरी तरह से गले लगाने के लिए :)। फिल्टर (एफ -> नॉन नल (एफ .get एन्नोटेशन (कॉलम.क्लास))) - dehumanizer


आप जेनेरिक प्रकारों का भी उपयोग कर सकते हैं, मेरे मामले में, कुछ भी करने से पहले जो कुछ भी कहा जा सकता है उसे ध्यान में रखते हुए:

public class SomeTypeManager<T> {

    public SomeTypeManager(T someGeneric) {

        //That's how you can achieve all previously said, with generic types.
        Annotation[] an = someGeneric.getClass().getAnnotations();

    }

}

याद रखें, यह 100Class.class.get (...) () पर 100% के बराबर नहीं होगा;

लेकिन चाल कर सकते हैं ...


2
2018-05-12 16:51





आपके पास सामान्य मामले में है निजी फ़ील्ड के लिए उपयोग, ताकि आप उपयोग नहीं कर सकते getFields प्रतिबिंब में। इसके बजाय आपको उपयोग करना चाहिए getDeclaredFields

तो, सबसे पहले, आपको पता होना चाहिए कि क्या आपके कॉलम एनोटेशन में रनटाइम प्रतिधारण है:

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

उसके बाद आप ऐसा कुछ कर सकते हैं:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}

जाहिर है, आप फ़ील्ड के साथ कुछ करना चाहते हैं - एनोटेशन वैल्यू का उपयोग करके नया मूल्य सेट करें:

Column annotation = f.getAnnotation(Column.class);
if (annotation != null) {
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
        object,
        myCoolProcessing(
            annotation.value()
        )
    );
}

तो, पूर्ण कोड इस तरह देखा जा सकता है:

for (Field f : MyClass.class.getDeclaredFields()) {
    Column annotation = f.getAnnotation(Column.class);
    if (annotation != null)
        new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
                object,
                myCoolProcessing(
                        annotation.value()
                )
        );
}

1
2017-10-19 07:12