2010-03-19 20 views
12

के लिए यह संभव (या यहां तक ​​की सलाह दी जाती है) तत्व बयान अपने आप में प्रत्येक कथन के लिए एक से लिया गया कास्ट करने के लिए? मुझे पता है कि सूची में प्रत्येक तत्व <SubType> प्रकार का होगा।जावा में कास्ट तत्व प्रत्येक बयान

यानी .:

List<BaseType> list = DAO.getList(); 
for(<SubType> element : list){ 
    // Cannot convert from element type <BaseType> to <SubType> 
    ... 
} 

बजाय:

List <BaseType> list = DAO.getList(); 
for(<BaseType> el : list){ 
    <SubType> element = (<SubType>)el; 
    ... 
} 

उत्तर

12

आप वास्तव में जानते हैं कि प्रत्येक प्रविष्टि एक उपप्रकार होने जा रहा है क्या? डीएओ को बस List<BaseType> अनुबंध को पूरा करना होगा, और यदि आप सबक्लास मान रहे हैं, तो मुझे लगता है कि कहीं कुछ गलत है। मैं शायद डीएओ को इंटरफ़ेस प्राप्त करने पर अधिक ध्यान केंद्रित करूँगा, और यह अनुबंधित रूप से वापस लौटाएगा जो आप चाहते हैं।

+0

+1 इतनी स्पष्ट रूप से अनुबंध तंत्र को बताते हुए इंटरफेस का पालन करना चाहिए। – aperkins

+1

दुर्भाग्यवश डीएओ कोड हमारा नहीं है। हालांकि, डेटासोर्स में फ़ीड हैं। हमने (केवल ऐसा सबक्लास) उपclassed क्योंकि हम कक्षा में अतिरिक्त कार्यक्षमता चाहते थे। चूंकि हम इनपुट को नियंत्रित करते हैं और हम केवल ऑब्जेक्ट्स डाल रहे हैं, मुझे लगता है कि मैं काफी हद तक निश्चित हो सकता हूं कि पुनर्प्राप्त वस्तु वास्तव में में से एक होगी। अगर हम सभी कोड नियंत्रित करते हैं, तो आप 100% सही होंगे। –

+3

@ करल - क्या डीएओ को लपेटने के लायक है, और एक * अलग * इंटरफ़ेस प्रदान करना जो आप चाहते हैं। अन्यथा आपको अपने सभी कोड बेस में कनवर्ट करना होगा (संभावित रूप से - मुझे एहसास है कि मैं इस बारे में धारणाएं कर रहा हूं कि यह कितना व्यापक रूप से वितरित किया गया है) –

1

संभव, हाँ! लेकिन भगवान मना कर दिया, क्यों? मेरे करियर में मेरे शुरुआती प्रयासों ने ऐसा किया और मैंने सीखा। इंटरफेस के लिए प्रोग्रामिंग हमेशा एक फायदा है। मुझे हमेशा जूनियर डेवलपर्स से ऐसे मामलों को संभालने के बारे में प्रश्न मिलते हैं जहां केवल उपप्रकारों के पास विधियों/कार्यक्षमता की आवश्यकता होती है।

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

मैं इस बारे में कठोर हूँ, कोई अगर यह केवल 1 उदाहरण बंद है मैं ठीक हूँ। अगर जवाब है तो मुझे यकीन नहीं है, तो आप इंटरफ़ेस अनुबंधों पर काम करके बेहतर खेलें।

12

सभी दूसरों द्वारा कहा कारणों के लिए, यदि आप ऐसा नहीं करना चाहिए। हालांकि, अगर आप इंटरफ़ेस को नहीं बदल सकते हैं, निम्नलिखित संभव है:

for (BaseType element : list) { 
    SubType subType = (SubType)element; 
    ... 
} 

जहाँ तक मुझे पता है, यह ऐसा करने के लिए एक ही रास्ता है और सही मायने में सुरक्षित टाइप रहते हैं - प्रकार विलोपन पर भरोसा नहीं अर्थात किसी भी पकड़ने के लिए समस्याएं, जो कि बाद में तब तक जरूरी नहीं होगी।

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

+0

मुझे ध्यान रखना चाहिए कि यदि आप इंटरफ़ेस बदल सकते हैं, और यह हमेशा सबटाइप होगा, तो आपको इंटरफ़ेस को बदलना चाहिए, चाहे वह उप-वर्ग एक्सटेंशन के माध्यम से हो या बस इसे बदल रहा हो। – aperkins

+2

वास्तव में सुरक्षित होने के लिए, आप कर सकते हैं: यदि (सबटाइप का तत्व उदाहरण) – VolatileDream

+0

बहुत सच - मुझे इसे रखना चाहिए था। – aperkins

0

आप गूगल संग्रह को आंशिक नहीं हैं, तो आप transform विधि के साथ सूची लपेट कर सकते हैं। आपके मामले में यह बहुत ही कुशल और पूरी तरह से अनुपालनशील होगा। ब्रायन ने सुझाव दिया है कि मैं इसे एक रैपर विधि के रूप में रखूंगा।

public List<SubType> fromDao () 
{ 
    // Put a comment for maintainer 

    // Lists from DAO always contain SubTypes 
    return 
     Lists.transform(
      DAO.getList(), 
      new Function< BaseType, SubType >() 
      { 
       public SubType apply (final BaseType from) 
       { 
        return (SybType) from; 
       } 
      }; 
} 
9

यह संभव वास्तव में डाली तो की तरह, पाश के लिए के साथ गठबंधन करने के लिए:

List<BaseType> list = DAO.getList(); 
for (SubType subType : ((List<SubType>) list)){ 
    ... 
} 

या आप इस थोड़ा-क्लीनर पैटर्न का उपयोग कर सकते हैं:

List<SubType> list = (List<SubType>) DAO.getList(); 
for (SubType subType : list){ 
    ... 
} 

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

ध्यान दें कि यह सरणी के साथ काम नहीं करेगा, क्योंकि सरणी के पास अलग-अलग रनटाइम प्रकार होते हैं। दूसरे शब्दों में, बेसटाइप [] सबटाइप [] के लिए जाति योग्य नहीं है। आप इस के आसपास काम करने के लिए Arrays API का उपयोग कर सकते हैं, जैसे:

BaseType[] array = DAO.getArray(); 
for (SubType subType : Arrays.<SubType>asList(array)) { 
    ... 
} 
+0

वे कलाकार कानूनी नहीं हैं, हालांकि आप [कुछ चाल] कर सकते हैं (https://stackoverflow.com/questions/933447/how-do-you-cast-a-list-of-objects-from-one-type- टू-ए-इन-जावा) इसके आसपास काम करने के लिए (जैसे इंटरमीडिएट कास्ट 'सूची '।) [जावा ट्यूटोरियल] (https://docs.oracle.com/javase/tutorial/java/generics/subtyping। एचटीएमएल) उस प्रश्न नोट से जुड़ा हुआ है: "हालांकि इंटीजर संख्या का उप प्रकार है, सूची सूची का उप प्रकार नहीं है और वास्तव में, इन दो प्रकारों से संबंधित नहीं हैं। सूची और सूची की सूची सामान्य सूची है । " –

+0

दूसरा उदाहरण काम करेगा यदि DAO.getList सूची की बजाय एक untyped सूची देता है। एक विरासत कोडबेस से निपटने के दौरान पैटर्न उपयोगी हो सकता है जहां संग्रहों में से कोई भी टाइप नहीं किया जाता है। – harperska

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