2011-10-21 19 views
5

कहो की ठोस प्रकार जाओ मैं निम्नलिखितजावा प्रतिबिंब: कार्यान्वित सामान्य इंटरफ़ेस

public class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
... 
} 

की तरह एक वर्ग यह AtomEntryHandler.class के वर्ग वस्तु से वर्ग वस्तु AtomEntry.class प्राप्त करने के लिए संभव है?

मुझे नहीं लगता था कि यह मिटाने के कारण संभव था, लेकिन एक दोस्त ने कहा।

+0

क्या आपके दोस्त ने कहा था? –

+2

नहीं, इसलिए सवाल :-D – ekj

+0

क्या एलेक्स गिटेलमैन का जवाब आपके लिए काम करता है? –

उत्तर

4

इंटरफ़ेस कार्यान्वयन के मामले में बेस प्रकार पैरामीटर निर्धारित करने का कोई तरीका नहीं मिला (जिसका मतलब यह नहीं है कि कोई भी नहीं है)। लेकिन यह उतना करीब है जितना इसे प्राप्त होता है।

import java.lang.reflect.*; 
public class Foo { 
    static class Bar<T> { 
    } 
    static class SubBar extends Bar<Integer> { 
    } 

    public static void main(String argv[]) { 
    ParameterizedType pt = (ParameterizedType)SubBar.class.getGenericSuperclass(); 
    Type[] t = pt.getActualTypeArguments(); 
    for (int i=0;i<t.length;i++) { 
     System.out.println(t[i]); 
    } 
    } 
} 

परिणाम: class java.lang.Integer

8

आप दोनों इंटरफेस और प्रत्यक्ष उपवर्गों के लिए सामान्य प्रकार प्राप्त कर सकते हैं, लेकिन केवल ठोस कार्यान्वयन के लिए। उदाहरण के लिए, यदि आपके पास List<T> उदाहरण है, तो आपके पास यह जानने का कोई तरीका नहीं है कि टाइप एरर के कारण इसे पैरामीटर किया गया है। यदि कक्षा परिभाषा में संकलित प्रकार शामिल हैं जो संकलन समय पर ज्ञात हैं (उदाहरण के लिए, class StringList extends List<String>) तो आप उस जानकारी को पुनर्प्राप्त कर सकते हैं।

ParameterizedType pt = (ParameterizedType)AtomEntryHandler.class.getGenericInterfaces()[0]; 
Class atomEntryClass = (Class)pt.getActualTypeArguments()[0]; 
+2

मैंने दस्तावेज़ में इंटरफ़ेस के बारे में पढ़ा है, लेकिन यदि वर्ग प्रश्न के अनुसार पैरामीटरयुक्त इंटरफ़ेस लागू करता है (और स्पष्ट रूप से किसी वर्ग को विस्तारित नहीं करता है), तो आपको 'पैरावाइज्ड टाइप' पर कास्टिंग करते समय 'java.lang.Object' और कास्ट अपवाद मिलेगा। –

+0

यदि आप 'getGenericSuperclass()' को कॉल करते हैं और आप स्पष्ट रूप से कुछ भी विस्तारित नहीं करते हैं या आप गैर-जेनेरिक वर्गों का विस्तार करते हैं, तो यह सच है, लेकिन यदि आप 'getGenericInterfaces()' को कॉल करते हैं तो कक्षा विरासत में कोई फर्क नहीं पड़ता क्योंकि यह केवल इससे निपट रहा है इंटरफेस। –

1

आप को पता है ConsumingHandler केवल इंटरफ़ेस AtomEntryHandler लागू करता है होता है, और आप को पता है कि यह सिर्फ एक प्रकार तर्क लेता है, तो आप ऐसा कर सकते हैं:

interface ConsumingHandler<T> {} 

class AtomEntry {} 

class AtomEntryHandler implements ConsumingHandler<AtomEntry> 
{ 
    public static void main(String[] args) 
    { 
     Type[] interfaces = AtomEntryHandler.class.getGenericInterfaces(); 
     ParameterizedType firstInterface = (ParameterizedType) interfaces[0]; 
     Class c = (Class) firstInterface.getActualTypeArguments()[0]; 
     System.out.println(c.getName()); // prints "AtomEntry" 
    } 
} 

अन्यथा, आप getGenericInterfaces() में चारों ओर से प्रहार कर सकते हैं और उनके actualTypeArguments जब तक कि आप ऐसा कुछ न ढूंढें जो आप ढूंढ रहे हैं।

लेकिन अगर आपको वास्तविक कोड में ऐसा करने की ज़रूरत है, तो शायद आपके डिजाइन में कुछ गलत हो गया है, या आप कुछ पागल प्रतिभा मॉक ऑब्जेक्ट लाइब्रेरी लिख रहे हैं और आपको इन सवालों के जवाब देने की आवश्यकता नहीं है।

+0

हाँ, मेरे पास इसके साथ एक खेल था, और यह कोड को जितना जटिल होना चाहिए उससे कहीं अधिक जटिल बनाता है। अगर यह आसान था तो इससे कुछ डुप्लिकेशंस से बचा होगा। – ekj

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