2009-04-10 15 views
15

मैं जावाजावा एनोटेशन

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface Column { 
    String columnName(); 
} 

और कक्षा में सरल एनोटेशन बना लिया है

public class Table { 

    @Column(columnName = "id") 
    private int colId; 

    @Column(columnName = "name") 
    private String colName; 

    private int noAnnotationHere; 

    public Table(int colId, String colName, int noAnnotationHere) { 
     this.colId = colId; 
     this.colName = colName; 
     this.noAnnotationHere = noAnnotationHere; 
    } 
} 

मुझे लगता है कि Column से एनोटेट सभी क्षेत्रों, से अधिक पुनरावृति और नाम और मूल्य प्राप्त करने की आवश्यकता क्षेत्र और एनोटेशन के। लेकिन मुझे प्रत्येक क्षेत्र के मूल्य प्राप्त करने में समस्या है, क्योंकि उनमें से सभी अलग-अलग डेटा प्रकार हैं।

क्या ऐसा कुछ भी है जो फ़ील्ड का संग्रह वापस करेगा जो एनोटेशन है? मैं इसे इस कोड के साथ करने में कामयाब रहा, लेकिन मुझे नहीं लगता कि प्रतिबिंब इसे हल करने का एक अच्छा तरीका है।

Table table = new Table(1, "test", 2); 

for (Field field : table.getClass().getDeclaredFields()) { 
    Column col; 
    // check if field has annotation 
    if ((col = field.getAnnotation(Column.class)) != null) { 
     String log = "colname: " + col.columnName() + "\n"; 
     log += "field name: " + field.getName() + "\n\n"; 

     // here i don't know how to get value of field, since all get methods 
     // are type specific 

     System.out.println(log); 
    } 
} 

मैं वस्तु में हर क्षेत्र है, जो getValue() की तरह विधि लागू करेगा रैप करने के लिए है, या वहाँ इस के आसपास कुछ बेहतर तरीका है? मूल रूप से मुझे केवल प्रत्येक फ़ील्ड की स्ट्रिंग प्रस्तुति की आवश्यकता है जो एनोटेटेड है।

संपादित करें: yep field.get(table) काम करता है, लेकिन केवल public फ़ील्ड के लिए, क्या private फ़ील्ड के लिए भी ऐसा करने का कोई तरीका है? या मुझे गेटटर बनाना है और किसी भी तरह इसे आमंत्रित करना है?

+0

सेट अक्षम। यदि आपके पास सुरक्षा प्रबंधक मौजूद है तो सरणी संस्करण तेज़ होगा। सेट असफल, निश्चित रूप से, परिस्थितियों में बहुत खतरनाक है जहां आपके पास सुरक्षा प्रबंधक है। –

+0

डरावना ...ऐसा लगता है कि आप जेपीए – basszero

+0

@basszero के अपने संस्करण को कार्यान्वित कर रहे हैं: हाँ, आप सही हैं, मुझे अपने कॉलेज प्रोजेक्ट के लिए यह करना है क्योंकि मेरे बेवकूफ शिक्षक जो गुफा में रहते हैं और किसी भी पुस्तकालय का उपयोग करने की अनुमति नहीं देते हैं जैसे कि टॉपलिंक इत्यादि ... –

उत्तर

11

प्रत्येक ऑब्जेक्ट को स्ट्रिंग() परिभाषित किया जाना चाहिए। (और आप प्रत्येक वर्ग के लिए अधिक सार्थक प्रतिनिधित्व प्राप्त करने के लिए इसे ओवरराइड कर सकते हैं)।

तो तुम जहाँ आपके "// यहाँ मैं नहीं जानता कि" टिप्पणी है, तो आप हो सकता है: बिल्कुल तरह से इसे हल करने

Object value = field.get(table); 
// gets the value of this field for the instance 'table' 

log += "value: " + value + "\n"; 
// implicitly uses toString for you 
// or will put 'null' if the object is null 
+0

thx, यह काम करता है, लेकिन केवल तभी जब फ़ील्ड सार्वजनिक रूप से घोषित किए जाते हैं, जब वे निजी होते हैं तो मुझे थ्रेड "मुख्य" java.lang में अपवाद मिलता है। IleglegalAccessException: क्लास मेन क्लास टेबल के सदस्य तक नहीं पहुंच सकता संशोधक "निजी" –

+0

@ डार्थ - फ़ील्ड.सेट एक्सेस करने योग्य पर एक नज़र डालें - http://java.sun.com/javase/6/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible(boolean) – McDowell

+0

@McDowell - thx जो समस्या हल करता है –

9

प्रतिबिंब है। निष्पादन समय पर प्रकारों और उनके सदस्यों के बारे में चीजों को ढूंढना प्रतिबिंब की परिभाषा बहुत अधिक है! जिस तरह से आपने किया है वह मेरे लिए ठीक दिखता है।

फ़ील्ड का मान की खोज करें, field.get(table)

4

प्रतिबिंब ठीक वैसी एनोटेशन को देखने के लिए है। वे वर्ग या विधि से जुड़े "मेटाडेटा" का एक रूप हैं, और जावा एनोटेशन को इस तरह से जांचने के लिए डिज़ाइन किया गया था।

+0

वाह, मैं जॉन के उत्तर के साथ पहले 5 शब्दों को साझा करता हूं, मुझे सुधार होना चाहिए :) – Uri

+2

यदि आप बारीकी से देखते हैं तो आप देखेंगे कि श्री स्कीट ने अपना तीसरा शब्द 'बिल्कुल सही रखा था 'इटालिक्स में जबकि आपकी प्रविष्टि केवल नियमित गैर-इटैलिक स्वरूपण में होती है। सही दिशा में एक कदम के लिए अच्छी तरह से किया गया लेकिन इस सूक्ष्म लेकिन इतने वर्णनात्मक जोर के बिना जो जॉन ने आपके पहले पांच शब्दों का उपयोग किया है, अभी भी श्री स्कीट से कम हो गया है। –

2

प्रतिबिंब वस्तु को संसाधित करने का एक तरीका है (शायद एकमात्र तरीका यदि फ़ील्ड निजी हैं और किसी भी प्रकार की एक्सेसर विधि नहीं है)। आपको Field.setAccessible और शायद Field.getType पर देखना होगा।

एक और तरीका compile-time annotation processor का उपयोग करके एनोटेटेड फ़ील्ड को गिनने के लिए एक और कक्षा उत्पन्न करना है। जावा 5 में com.sun एपीआई की आवश्यकता है, लेकिन जावा 6 जेडीके में समर्थन बेहतर है (ग्रहण जैसे आईडीई विशेष परियोजना कॉन्फ़िगरेशन की आवश्यकता हो सकती है)।

संबंधित मुद्दे