2012-01-03 16 views
7

मैंवेरिएबल प्रकार तर्क के साथ जेनेरिक

public interface Foo<R, P...> { 
    public R bar(P...) {/*misc*/} 
} 

की तरह कुछ करने के लिए मेरे बाध्य कार्यान्वयन में उपयोग करने के लिए प्रकार की एक सरणी प्राप्त करना चाहते हैं। क्या यह जावा में संभव है?

वरर्ग को किसी दिए गए वर्ग के किसी भी तर्क के लिए डिज़ाइन करने के लिए डिज़ाइन किया गया है।

मैं इसे (या कुछ इसी तरह) का उपयोग करने के लिए अपने विधि कई तर्क, किसी दिए गए विभिन्न वर्ग के एक सदस्य है, जिनमें से प्रत्येक को स्वीकार करना चाहते हैं। ये वर्ग परिभाषित किए जाते हैं जब जेनेरिक बाध्य होता है।

मुझे पता है काम arounds हैं, लेकिन यह करने के लिए एक प्रकार का सुरक्षित तरीका है?

+0

अब तक जो मिला है उसके साथ क्या गलत है? एकमात्र मुद्दा यह है कि वैरैग जेनेरिक के साथ बहुत अच्छी तरह से नहीं खेलता है। –

उत्तर

7

जब से तुम जाहिरा तौर पर barविभिन्न प्रकार के कई मापदंडों लेने के बनाने के लिए सक्षम होना चाहते हैं (कुछ varargs नहीं के लिए इस्तेमाल कर रहे हैं), मैं इसे बजाय एक ही पैरामीटर बनाने सुझाव देना चाहेंगे। फिर आप उस एकल पैरामीटर को एक कंटेनर बना सकते हैं जिसमें प्रत्येक "पैरामीटर" का उपयोग करना है जिसे आप उपयोग करना चाहते हैं।

सामान्य तौर पर, यह सबसे अच्छा होगा मापदंडों ताकि आप वस्तुओं इसमें से प्रत्येक के लिए अच्छा नाम है इस विधि के साथ उपयोग करना चाहते हैं के प्रत्येक सेट के लिए एक वर्ग बनाने के लिए होगा। हालांकि, होल्डर के रूप में उपयोग करने के लिए आप टुपल प्रकारों (जैसे Pair) की श्रृंखला बनाने जैसी कुछ भी कर सकते हैं।

public class Foo<R, P> { 
    /* 
    * Not sure how you intend to provide any kind of implementation 
    * here since you don't know what R or P are. 
    */ 
    public R bar(P parameters) { ... } 
} 

public class SomeFoo extends Foo<SomeResult, Pair<Baz, Bar>> { 
    public SomeResult bar(Pair<Baz, Bar> parameters) { ... } 
} 

SomeFoo foo = ... 
SomeResult result = foo.bar(Pair.of(baz, bar)); 
+0

मुझे लगता है कि यह एक अच्छा विचार है, यह बाध्यकारी वर्ग को कंटेनर/ट्यूपल ऑब्जेक्ट में लपेटकर, संख्याओं और तर्कों के प्रकार को परिभाषित करने की अनुमति देता है। मूल पुस्तकालयों/जेडीके के tuple/जोड़ी हिस्सा हैं? मैं उन्हें नहीं ढूंढ सका, हालांकि मुझे लगता है कि यह खुद लिखने के लिए तुच्छ होगा। क्या मैं यह सुझाव देने के लिए सही होगा कि जावा में tuples वास्तव में सी में structs की भूमिका पूरी करते हैं? –

+2

आम तौर पर मैं ट्यूपल प्रकार बनाने से बचूंगा (वे जेडीके में मौजूद नहीं हैं क्योंकि वे विभिन्न कारणों से अच्छी तरह से काम नहीं करते हैं) और वास्तविक कक्षाएं बनाते हैं जो प्रत्येक निहित वस्तु को उपयोगी नाम देते हैं। मैंने ज्यादातर उल्लेख किया है कि क्योंकि यह आपके अनुरोध के लिए प्रतीत होता है और क्योंकि यह आपके पास एक विकल्प है। संक्षिप्त जवाब यह है कि यदि आप मनमाने ढंग से वस्तुओं की मनमानी संख्या को समूहबद्ध करना चाहते हैं, तो कक्षा जाने का रास्ता है। आप एक वर्ग को बहुत छोटा और सरल बना सकते हैं और इसे मूल रूप से एक संरचना के रूप में कार्य कर सकते हैं। – ColinD

+1

ग्रहण में वास्तव में यह करने के लिए एक सुविधा है: 'refactor> पैरामीटर ऑब्जेक्ट ' – AJMansfield

2

आप ने लिखा है::

यहाँ एक उदाहरण है

मैं इसे (या कुछ इसी तरह) का उपयोग करने के लिए अपने विधि कई तर्क स्वीकार करते हैं, जिनमें से प्रत्येक का एक सदस्य है करना चाहते हैं एक दिया गया अलग वर्ग।

मैं इसे वस्तु के साथ कक्षा का एक उदाहरण सहित जैसे कुछ बदसूरत हैक्स के बिना एक प्रकार सुरक्षित तरीके से ऐसा करने के लिए, संभव है नहीं लगता।

समस्या यह है कि varargs साथ आप वास्तव में किसी सरणी में पारित किया जा रहा हो जाता है। लेकिन आपके पास विभिन्न प्रकार की वस्तुओं के साथ एक सरणी नहीं हो सकती है, उन्हें सभी को समान (या उप-वर्ग होना चाहिए, इसलिए यदि आपके पास एक्स [] y है तो प्रत्येक तत्व एक्स का उप-वर्ग होना चाहिए)

यदि आपका फ़ंक्शन वास्तव में कई प्रकारों से निपट सकता है जो आप कक्षा के समान कुछ बना सकते हैं जो कक्षा के उदाहरण के साथ कक्षा के उदाहरण को संग्रहीत करता है, और उस कंटेनर की एक var args सूची में पास करता है।

इसलिए उदाहरण के लिए आप

class TypedInstance<T>{ 
    Class<T> type; 
    T instance; 
} 

हो सकता था और फिर एक समारोह है कि जैसे

public whatever(TypedInstance<? extends Object>... whatever){ 
    ... 
    doSomethingWith(whatever[0].type, whatever[0].instance); 
    ... 
} 

हैक्स के इन प्रकार के जावा के प्रकार विलोपन की वजह से की जरूरत है कुछ दिखता है। जेनेरिक पैरामीटर रनटाइम पर हटा दिया जाता है, इसलिए यदि आप इसका उपयोग करना चाहते हैं, तो आपको इसे वापस रखना होगा।

+0

+1 परिचय अच्छा विचार है, लेकिन फ़ंक्शन कभी भी पी का उपयोग नहीं करता है। पैरामीटर प्रकारों के लिए कोई प्रकार-सुरक्षा नहीं है, इसके अलावा उन्हें ऑब्जेक्ट का विस्तार करना है। उदाहरण के द्वारा 'instance' प्रकार का अधिग्रहण किया जा सकता है .getClass(); मूल रूप से आप टाइप टी का एक उदाहरण रैपर में लपेट रहे हैं, जो थोड़ा सा व्यर्थ है। –

+0

सच है, लेकिन इसे सीधे करने का कोई वास्तविक तरीका नहीं है ... हालांकि नेस्टेड टुपल्स का उपयोग करने के कॉलिन डी का विचार बहुत शानदार है। मुझे योजना/लिस्पी में चीजों के तरीके के बारे में याद दिलाता है। –

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