2011-06-01 14 views
5

जावा में प्रतिबिंब का उपयोग करते हुए एक साधारण JSON serialiser लिखते समय मुझे class.getMethods() के व्यवहार से गार्ड को पकड़ा गया था। ऐसा प्रतीत होता है कि जावा क्लास.getMethods() ओवरराइडिंग विधि के ओवरराइडिंग विधि का रिटर्न प्रकार विस्तारित करता है, तो ओवरराइडिंग और ओवरराइड विधियों दोनों को लौटाता है।
इसलिए उदाहरण के लिए दिए गए इंटरफेस:ओवरराइड विधियों पर जावा क्लास.getMethods() व्यवहार

static interface A { 
    A x(); 
    A y(); 
} 
static interface B extends A { 
    B x(); 
    A y(); 
} 

A.class.getMethods() रिटर्न और दो तरीकों में से सरणी के रूप में की उम्मीद तथापि B.class.getMethods() 3 तरीकों की एक सरणी (जो मेरे लिए थोड़ा काउंटर सहज ज्ञान युक्त था) देता है। 3 में से 1, y() के अनुरूप होने के अनुरूप है लेकिन शेष दो मूल x() से संबंधित प्रकार A और x() के ओवरराइडिंग संस्करण क्रमशः B के साथ मेल खाते हैं। इसने मुझे थोड़ा अजीब के रूप में मारा लेकिन सरणी में मूल x() क्योंकि यह कहीं से भी उपलब्ध नहीं है। वैसे भी मेरा सवाल यह है:
क्या कक्षा के तरीकों के केवल सबसे विशेष संस्करणों की सूची प्राप्त करने का कोई आसान तरीका है बिना मैन्युअल रूप से ओवरराइड विधियों की जांच करने और उन्हें फ़िल्टर करने का उपयोग किए बिना?

उत्तर

6

मेरी समझ यह है कि यदि आप उन तरीकों को फ़िल्टर करते हैं जिनके लिए isBridge()true लौटाता है, तो अवांछित विधि दूर जाना चाहिए।

यह एक आर्टेफैक्ट है कि कैसे जावा कॉन्वर्सेंट रिटर्न प्रकार लागू करता है (जेनिक्स के लिए ब्रिज विधियों का भी उपयोग किया जाता है, लेकिन यह आपके उपयोग के मामले के लिए प्रासंगिक नहीं दिखता है)।

संपादित करें दिलचस्प बात यह है कि यह कक्षाओं के लिए काम करता है, यह इंटरफेस के लिए काम नहीं करता है। B के सभी तीन तरीकों को गैर-पुल और गैर सिंथेटिक के रूप में चिह्नित किया गया है। हालांकि, अगर मैं एक गैर-अमूर्त वर्ग CB लागू करने के लिए बनाता हूं, तो इसके A x() को पुल और सिंथेटिक दोनों के रूप में चिह्नित किया जाता है।

+0

यही व्यवहार काफी उम्मीद है, के रूप में इंटरफेस सिर्फ तरीकों घोषित करने के लिए उपयोग किया जाता है, तो सिंथेटिक (संकलक द्वारा बनाई गई) नहीं हैं । –

0

एक तरीका यह है कि: B.class.getDeclaredMethods(), हालांकि, यह केवल बी में घोषित विधियों को वापस कर देगा। इसलिए, यदि आपके पास बी लागू करता है तो ए, C.class.getDeclaredMethods() उन विधियों को वापस नहीं लौटाएगा जिन्हें आपने ओवरराइड नहीं किया है।

अगर आप पुनरावृति करना चाहते हैं, ऐसा करने के लिए अच्छा तरीका

for (Method m: B.class.getMethods()) { 
    if (m.getDeclaringClass() == Object.class || m.declaringClass() == A.class) 
    continue; 
    // otherwise do some stuff 
} 
3

है तुम क्या है "covariant वापसी" कहा जाता है।

ऐक्स बताते हैं, ऐसा लगता है कि आपको पुल विधियों से निपटना होगा। इस पढ़ें: http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html (जेनरिक के बारे में पाठ पर ध्यान न दें) और इस: Problem in the GetDeclaredMethods (java)

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