2009-07-13 13 views
17

जावा में, क्या फ़ील्ड/वैरिएबल घोषित करना संभव है जिसका प्रकार एकाधिक इंटरफेस है? उदाहरण के लिए, मुझे Map घोषित करने की आवश्यकता है जो Serializable भी है। मैं यह सुनिश्चित करना चाहता हूं कि परिवर्तनीय संदर्भ एक क्रमिक मानचित्र है। Map इंटरफ़ेस Serializable का विस्तार नहीं करता है, लेकिन Map के अधिकांश कार्यान्वयन Serializable हैं।जावा, एकाधिक इंटरफेस के साथ परिवर्तनीय घोषित करें?

मुझे पूरा यकीन है कि उत्तर नहीं है।

अनुवर्ती: मुझे लगता है कि Map और Serializable दोनों फैली हुई है एक नया इंटरफेस बनाने से पूरी तरह वाकिफ हूँ। यह मौजूदा कार्यान्वयन के रूप में काम नहीं करेगा (जैसे HashMap) मेरा नया इंटरफ़ेस लागू न करें।

उत्तर

7

कोई जरूरत नहीं है इस तरह के क्षेत्र/चर घोषित करने के लिए। खासकर जब से इसे केवल रनटाइम का परीक्षण किया जा सकता है और समय संकलित नहीं किया जा सकता है। एक सेटर बनाएं और एक त्रुटि रिपोर्ट करें, पास किए गए मानचित्र को Serializable लागू नहीं करना चाहिए।

उत्तर देने का उत्तर यह है कि आप अपना इंटरफ़ेस बनाते हैं, बिल्कुल व्यावहारिक नहीं हैं क्योंकि वे सक्रिय रूप से उन चीज़ों को भेजने पर रोक लगाएंगे जो मैप्स और सीरियलज़ेबल हैं लेकिन आपका विशेष इंटरफ़ेस नहीं है।

+0

भले ही 'मैप' 'Serializable' लागू करता है, इसका मतलब यह नहीं है कि यह धारावाहिक है। लेकिन जावा जावा serialisability जावा में एक रनटाइम मुद्दा है। दुर्भाग्य से जावा के लिए –

+0

, यह सही उत्तर है और शीर्ष पर होने का हकदार है। – hythlodayr

+0

आपने मेरे उत्तर के महत्वपूर्ण भाग को याद किया ... आप मानचित्र स्वीकार करते हैं और फिर जांचें कि ऑब्जेक्ट एक उदाहरण है जो Serializable है। आप निश्चित रूप से इसे दूसरी तरफ कर सकते हैं लेकिन फिर आपको एक इंटरफ़ेस मिलेगा जो वास्तव में उपयोगकर्ता को यह नहीं बताएगा कि आप किस प्रकार का संग्रह चाहते हैं। – Fredrik

6
public interface MyMap extends Map, Serializable { 
} 

Map और Serializable का मिलन है कि एक नए इंटरफ़ेस परिभाषित करेगा।

आप स्पष्ट रूप से तो इस का एक उपयुक्त कार्यान्वयन (जैसे MyMapImpl) प्रदान करने के लिए है और आप तो चर (या आवश्यकताओं के आधार पर Map, या Serializable,) प्रकार MyMap के संदर्भ प्रदान कर सकते हैं।

अपनी स्पष्टीकरण को संबोधित करने के लिए, आप व्यवहार को फिर से शुरू नहीं कर सकते (उदा। एक क्रमिक मानचित्र)। इंटरफ़ेस और कुछ उचित कार्यान्वयन के लिए में है।

+2

मुझे लगता है कि वह मौजूदा वस्तुओं को चर के लिए असाइन करना चाहता था, उदा। एक हैश मैप ऑब्जेक्ट। – skaffman

+2

मुझे लगता है कि वह एक परिवर्तनीय हस्ताक्षर के रूप में एक serializable मानचित्र होना चाहता है, लेकिन अभी भी हैश मैप, TreeMap, आदि का उपयोग करने में सक्षम हो। आई।, MyMap मानचित्र = नया हैश मैप(); मुझे लगता है कि काम करने के लिए नहीं जा रहा है। – JeeBee

3

आप

public interface SerializableMap<K, V> extends Map<K, V>, Serializable { 

} 
11

आप जेनरिक के साथ यह कर सकते हैं चाहते हैं अपने स्वयं के इंटरफेस है, जो इंटरफेस फैली बनाकर इस लक्ष्य को हासिल कर सकते हैं, लेकिन यह काफी नहीं है:

class MyClass<T,K,V extends Serializable & Map<K,V>> { 

    T myVar; 

} 
+1

शायद उस पर एक के एंड वी जोड़ना चाहते हैं। –

+0

आपको आम तौर पर इसका उपयोग करने में कितनी कुरूपता की आवश्यकता होती है। –

+0

हां, यह बड़ा चूसना होगा, और मैं ऊपर लिखने के बजाय अपने स्वयं के नाखूनों को खींचूंगा, लेकिन दूसरे आदमी ने यहां पैसे का भुगतान किया है। – skaffman

0

यदि आप मौजूदा Map कार्यान्वयन का उपयोग करना जारी रखना चाहते हैं तो आप वास्तव में ऐसा नहीं कर सकते हैं।

एक वैकल्पिक एक सहायक वर्ग बनाने के लिए, और इस तरह एक विधि को जोड़ने के लिए होगा:

public static Serializable serializableFromMap(Map<?, ?> map) { 
    if (map instanceof Serializable) { 
     return (Serializable)map; 
    } 
    throw new IllegalArgumentException("map wasn't serializable"); 
} 
2

मैं ब्रायन के जवाब को वोट किया है, लेकिन एक छोटे से उच्च स्तर के बारे में सोचा जोड़ना चाहते थे ..

यदि आप एसडीके देखते हैं, तो आप पाएंगे कि वे शायद ही कभी (यदि कभी) वास्तविक संग्रह वस्तुओं के आसपास गुजरते हैं।

इसका कारण यह है कि यह एक बहुत अच्छा विचार नहीं है। संग्रह बेहद असुरक्षित हैं।

अधिकांश समय आप इसे पारित करने से पहले एक प्रतिलिपि बनाना चाहते हैं और प्रतिलिपि पास करना चाहते हैं ताकि संग्रह में कोई भी संशोधन उस पर निर्भर किसी अन्य चीज़ के लिए पर्यावरण को नहीं बदलेगा।इसके अलावा, थ्रेडिंग एक दुःस्वप्न बन जाती है - यहां तक ​​कि एक सिंक्रनाइज़ संग्रह के साथ भी!

मैंने दो समाधान देखा है, एक हमेशा एक सरणी निकालने और इसे पास करने के लिए है। एसडीके यह करता है।

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

"विधि (संग्रह, ...)" से मेल खाने वाले हस्ताक्षर वाले किसी भी विधि को निश्चित रूप से उस संग्रह का सदस्य विधि होना चाहिए, जैसा कि संग्रह पर पुनरावृत्ति करने वाले किसी भी लूप को होना चाहिए।

मुझे बस इसे हर बार फेंकना है और फिर क्योंकि यह उन चीजों में से एक है जो मुझे थोड़ी देर तक नहीं मिला (क्योंकि कोई भी अवधारणा को चैंपियन नहीं करता था)। ऐसा लगता है कि इसमें कुछ कमी आएगी लेकिन थोड़ी देर के लिए ऐसा करने और समस्याओं को हल करने और इसे समाप्त करने के कोड को देखते हुए, मैं किसी भी संभावित दोष की कल्पना भी नहीं कर सकता, यह सब ठीक है।

+0

मैं इसके साथ सहमत हूं। यह मुझे स्पष्ट नहीं है कि हाथ से कोड के लिए विशिष्ट कुछ अर्थपूर्ण रूप से सार्थक इंटरफ़ेस की बजाय मनमाने ढंग से मौजूदा 'मानचित्र की वांछनीय क्यों स्वीकार्य है। –

6

यह संभव है कुछ जेनरिक चाल का उपयोग कर ऐसा करने के लिए:

public <T extends Map<?,?> & Serializable> void setMap(T map) 

ऊपर कोड जेनरिक का उपयोग करता है एक नक्शा है जो दोनों इंटरफेस को लागू करता है पारित करने के लिए आप के लिए मजबूर करने। हालांकि, ध्यान दें कि इसका नतीजा यह है कि जब आप वास्तव में इसे नक्शे पास करते हैं, तो उन्हें शायद क्रमशः या एक नक्शा प्रकार के रूप में चिह्नित किया जाना चाहिए जो पहले से ही क्रमबद्ध है। यह पढ़ने के लिए थोड़ा और मुश्किल भी है। मैं दस्तावेज करता हूं कि नक्शा क्रमबद्ध होना चाहिए और इसके लिए परीक्षण करना चाहिए।

0

नहीं, आपको बहुत अधिक डालने की आवश्यकता होगी।

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