2013-01-02 21 views
16

इन दोनों (वैध) सामान्य सीमा हो:वहाँ सामान्य सीमा "Enum <T> और फू" और के बीच एक अंतर है "Enum <फैली फू?>"

<T extends Enum<T> & MyInterface> 
<T extends Enum<? extends MyInterface>> 

एक ही?


मान लीजिए मैं एक अंतरफलक

interface MyInterface { 
    void someMethod(); 
} 

और कुछ enums कि इसे लागू:

enum MyEnumA implements MyInterface { 
    A, B, C; 
    public void someMethod() {} 
} 

enum MyEnumB implements MyInterface { 
    X, Y, Z; 
    public void someMethod() {} 
} 

और मैं एक कार्यान्वयन का उपयोग करता है MyInterface न केवल एक बल्कि यह है कि आवश्यकता करना चाहते हैं एक enum है "मानक" जिस तरह से एक चौराहे बाध्य कर रहा है:

static class MyIntersectionClass<T extends Enum<T> & MyInterface> { 
    void use(T t) {} 
} 

लेकिन मुझे पता चला है कि यह काम करता है:

static class MyWildcardClass<T extends Enum<? extends MyInterface>> { 
    void use(T t) {} 
} 
ऊपर के साथ

, इस संकलित:

public static void main(String[] args) throws Exception { 
    MyIntersectionClass<MyEnumA> a = new MyIntersectionClass<MyEnumA>(); 
    a.use(MyEnumA.A); 
    MyWildcardClass<MyEnumB> b = new MyWildcardClass<MyEnumB>(); 
    b.use(MyEnumB.X); 
} 

और बाध्य काम करता है और इरादे से दोनों मामलों के लिए आवश्यक है।

क्या इन दो सीमाओं के बीच कोई अंतर है, यदि ऐसा है, और दूसरे की तुलना में एक "बेहतर" है?

+1

वे सही मायने में समझदार हैं, क्योंकि यह 'नहीं करता है मैं चौराहे पसंद करते हैं वाइल्डकार्ड का उपयोग नहीं करते, जिसे मैं व्यक्तिगत रूप से "अशुद्ध" – Bohemian

उत्तर

4

इस विशिष्ट मामले में कोई अंतर नहीं है क्योंकि Enums औपचारिक प्रकार पैरामीटर प्रभावी ढंग से स्वयं प्रकार है। इसका कारण यह है एक तो जैसे Enum से विरासत नहीं कर सकते:

class MyEnumA extends Enum<MyEnum2> {} 
class MyEnumB implements MyInterface {} 

तो हाँ, वे एक ही अर्थ की दृष्टि से बाध्य कर रहे हैं, लेकिन केवल क्योंकि यह Enum है।

+0

+1 और "बेहतर" वाक्यविन्यास क्या है, इस पर समय बर्बाद नहीं करने के बाद, वे एक ही चीज़ को देखते हैं। –

+0

+1 लेकिन आप 'java.lang.Enum' का विस्तार नहीं कर सकते, क्या आप कर सकते हैं? – Saintali

1

वे वही काम करेंगे, लेकिन मैं कहूंगा कि T extends Enum<? extends MyInterface> थोड़ा अधिक मानक है और इस प्रकार बेहतर है, अगर केवल इसलिए कि यह अधिक सामान्य और जल्दी से पहचानने योग्य है। कई लोगों को जेनेरिक के & भाग के बारे में भी पता नहीं है।

आप यह भी तर्क दे सकते हैं कि वे थोड़ा अलग पढ़ते हैं। T extends Enum<T> & MyInterface मैं "एक enum जो एक MyInterface भी होता है के रूप में पढ़ा जाएगा।" T extends Enum<? extends MyInterface> मैं "एक enum जो MyInterface लागू करता है" के रूप में पढ़ा होगा। तो उस हद तक, यह व्यक्तिगत वरीयता का मामला है; मैं बाद वाले को पसंद करता हूँ।

+0

-1 क्षमा करता हूं, लेकिन पहले खंड के बाद सब कुछ व्यक्तिपरक और रचनात्मक नहीं है। –

+2

@ पॉलबेलोरा ओपी के प्रश्न में सवाल शामिल था, और 'दूसरे की तुलना में एक "बेहतर" है। यह स्वाभाविक रूप से एक व्यक्तिपरक प्रश्न है, इसलिए सवाल का जवाब देने के लिए लोगों को डॉक करने के लिए अनुचित लगता है। आपके डाउनवॉट निश्चित रूप से वितरित करने के लिए हैं, लेकिन मुझे लगता है कि आपकी तर्क एसओ [डाउनवॉट्स के लिए सुझाव] (http://stackoverflow.com/privileges/vote-down) को रोकती है, क्योंकि यह स्पष्ट रूप से या शायद खतरनाक रूप से गलत नहीं है, और मैं 'डी तर्क है कि यह मैला नहीं है या कोई प्रयास नहीं किया गया है। – yshavit

+0

यह पहली बार है जब मैंने आपको कम किया है और मैं वादा करता हूं कि मैंने इसके बारे में सोचा था। इसे व्यक्तिगत रूप से न लें :) –

2

चूंकि दूसरा व्यक्ति विशेष तथ्य पर निर्भर करता है कि जावा एनम्स को MyEnum extends Enum<MyEnum> के रूप में कार्यान्वित किया गया है, तो मैं पहले व्यक्ति को पसंद करूंगा, जो ऐसी धारणाओं पर भरोसा नहीं करता है और आपकी बाधाओं को स्पष्ट रूप से बताता है।

3

के रूप में अन्य लोगों ने बताया है, दोनों वाक्यविन्यास एक ही सीमा को प्राप्त - और केवल क्योंकि enums, जहां हम जानते हैं Enum<T> में T तुरंत विस्तार enum प्रकार होना चाहिए के विशेष मामले के। तो T को संकुचित करने में हल किया जा सकता है, इसमें कोई फर्क नहीं पड़ता है।

T के उदाहरणों के संभावित उपयोग में एक अंतर है, लेकिन शायद यह इतनी बारीकियों है कि यह अप्रासंगिक है।विचार करें कि निम्न कथन MyIntersectionClass.use में संकलित नहीं बल्कि MyWildcardClass.use:

T t2 = t.getDeclaringClass().newInstance(); 

केवल इन उत्तरार्द्ध में संकलन होगा:

MyInterface t2 = t.getDeclaringClass().newInstance(); 
Enum<? extends MyInterface> t3 = t.getDeclaringClass().newInstance();