यह संकलन नहीं है, किसी भी सुझाव की सराहना की।
...
List<Object> list = getList();
return (List<Customer>) list;
संकलक का कहना है: डाली नहीं कर सकते List<Object>
करने के लिएList<Customer>
यह संकलन नहीं है, किसी भी सुझाव की सराहना की।
...
List<Object> list = getList();
return (List<Customer>) list;
संकलक का कहना है: डाली नहीं कर सकते List<Object>
करने के लिएList<Customer>
जवाबों:
आप हमेशा किसी भी प्रकार के किसी भी ऑब्जेक्ट को पहले ऑब्जेक्ट पर अप-कास्टिंग करके डाल सकते हैं। आपके मामले में:
(List<Customer>)(Object)list;
आपको यकीन होना चाहिए कि रनटाइम में सूची में ग्राहक वस्तुओं के अलावा कुछ नहीं है।
आलोचकों का कहना है कि इस तरह की कास्टिंग आपके कोड के साथ कुछ गलत होने का संकेत देती है; इससे बचने के लिए आपको अपनी प्रकार की घोषणाओं को करने में सक्षम होना चाहिए। लेकिन जावा जेनरिक बहुत जटिल है, और यह सही नहीं है। कभी-कभी आप बस यह नहीं जानते हैं कि संकलक को संतुष्ट करने के लिए एक सुंदर समाधान है, भले ही आप रनटाइम प्रकार को अच्छी तरह से जानते हैं और आप जानते हैं कि आप जो करने की कोशिश कर रहे हैं वह सुरक्षित है। उस मामले में, बस आवश्यकतानुसार कच्चे कास्टिंग करें, ताकि आप घर के लिए काम छोड़ सकें।
@SuppressWarnings("unchecked")
। ध्यान दें कि आप (List)
इसके बजाय ऊपर भी कर सकते हैं (Object)
।
ऐसा इसलिए है क्योंकि ग्राहक एक वस्तु है, ग्राहकों की सूची वस्तुओं की सूची नहीं है । अगर ऐसा होता, तो आप किसी भी वस्तु को ग्राहकों की सूची में डाल सकते थे।
.Cast<T>()
और एक कॉल .OfType<T>()
। पूर्व प्रत्येक तत्व पर एक कलाकार करता है (वांछित अपवादों को फेंकते हुए), जबकि बाद वाले तत्वों को फ़िल्टर नहीं किया जा सकता है (इसलिए आप अपने उपयोग परिदृश्य के आधार पर एक को चुनेंगे)।
instanceof
ग्राहक नहीं है तो क्या होगा ?
आपके अन्य कोड के आधार पर सर्वश्रेष्ठ उत्तर भिन्न हो सकते हैं। प्रयत्न:
List<? extends Object> list = getList();
return (List<Customer>) list;
या
List list = getList();
return (List<Customer>) list;
लेकिन ध्यान रखें कि ऐसी अनियंत्रित जातियों को करने की अनुशंसा नहीं की जाती है।
जावा 8 धाराओं के साथ :
कभी-कभी जानवर बल कास्टिंग ठीक है:
List<MyClass> mythings = (List<MyClass>) (Object) objects
लेकिन यहाँ एक और अधिक बहुमुखी समाधान है:
List<Object> objects = Arrays.asList("String1", "String2");
List<String> strings = objects.stream()
.map(element->(String) element)
.collect(Collectors.toList());
लाभ का एक टन है, लेकिन एक यह है कि आप अपनी सूची को और अधिक सुरुचिपूर्ण ढंग से रख सकते हैं यदि आप सुनिश्चित नहीं कर सकते हैं कि इसमें क्या शामिल है:
objects.stream()
.filter(element->element instanceof String)
.map(element->(String)element)
.collect(Collectors.toList());
FluentIterable
ने मेरे लिए काम किया।
ध्यान दें कि मैं कोई जावा प्रोग्रामर नहीं हूं, लेकिन .NET और C # में, इस सुविधा को कंट्रोवर्सी या कोवरियन कहा जाता है। मैंने अभी तक उन चीजों में देरी नहीं की है, क्योंकि वे .NET 4.0 में नए हैं, जिसका मैं उपयोग नहीं कर रहा हूं क्योंकि यह केवल बीटा है, इसलिए मुझे नहीं पता कि दोनों में से कौन सी शर्तें आपकी समस्या का वर्णन करती हैं, लेकिन मुझे वर्णन करें इसके साथ तकनीकी समस्या।
मान लेते हैं कि आपको कास्ट करने की अनुमति दी गई थी। ध्यान दें, मैं कास्ट कहता हूं , क्योंकि आपने जो कहा है, लेकिन दो ऑपरेशन हैं जो संभव हो सकते हैं, कास्टिंग और परिवर्तित करना ।
परिवर्तित करने का अर्थ यह होगा कि आपको एक नई सूची ऑब्जेक्ट मिल जाएगी, लेकिन आप कहते हैं कि कास्टिंग, जिसका अर्थ है कि आप अस्थायी रूप से एक वस्तु को दूसरे प्रकार के रूप में व्यवहार करना चाहते हैं।
यहाँ उस के साथ समस्या है।
यदि निम्नलिखित की अनुमति दी जाती है तो क्या होगा (ध्यान दें, मैं यह मान रहा हूं कि कलाकारों से पहले, वस्तुओं की सूची में वास्तव में केवल ग्राहक ऑब्जेक्ट होते हैं, अन्यथा कलाकार जावा के इस काल्पनिक संस्करण में भी काम नहीं करेंगे):
List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];
इस मामले में, यह एक वस्तु का इलाज करने का प्रयास करेगा, जो ग्राहक के रूप में ग्राहक नहीं है, और आपको एक बिंदु पर रनटाइम त्रुटि मिलेगी, या तो सूची के अंदर, या असाइनमेंट से फॉर्म।
जेनरिक, हालांकि, आपको संग्रह की तरह, सुरक्षित-सुरक्षित डेटा प्रकार देने के लिए माना जाता है, और चूंकि वे 'गारंटीकृत' शब्द को चारों ओर फेंकना पसंद करते हैं, इस तरह की कास्ट, जो समस्याओं का पालन करती हैं, की अनुमति नहीं है।
.NET 4.0 में (मुझे पता है, आपका प्रश्न जावा के बारे में था), यह कुछ बहुत ही विशिष्ट मामलों में अनुमति दी जाएगी , जहां कंपाइलर गारंटी दे सकता है कि आपके द्वारा किए जाने वाले ऑपरेशन सुरक्षित हैं, लेकिन सामान्य अर्थ में, इस प्रकार का कास्ट नहीं होगा अनुमति पाना। वही जावा के लिए है, हालांकि मैं किसी भी योजना के बारे में अनिश्चित हूँ जो जावा भाषा के साथ सह-विरोधाभासी है।
उम्मीद है, मुझसे बेहतर जावा ज्ञान वाला कोई व्यक्ति आपको जावा भविष्य या कार्यान्वयन के बारे में बता सकता है।
List<Customer> cusList = new ArrayList<Customer>();
for(Object o: list){
cusList.add((Customer)o);
}
return cusList;
list.stream().forEach(x->cusList.add((Customer)x))
return cuslist;
आप नहीं कर सकते हैं List<Object>
और List<Customer>
एक ही वंशानुक्रम में नहीं हैं।
आप अपनी List<Customer>
क्लास में एक नया कंस्ट्रक्टर जोड़ सकते हैं List<Object>
जो लिस्ट में से प्रत्येक के माध्यम Object
से एक को कास्टिंग कर रहा है Customer
और इसे अपने कलेक्शन में जोड़ रहा है। ध्यान रखें कि कॉल करने वाले के पास List<Object>
कुछ ऐसा नहीं होने पर एक अमान्य कास्ट अपवाद हो सकता है Customer
।
जेनेरिक सूचियों का बिंदु उन्हें कुछ प्रकारों के लिए विवश करना है। आप एक सूची लेने की कोशिश कर रहे हैं, जिसमें कुछ भी हो सकता है (आदेश, उत्पाद, आदि) और इसे एक सूची में निचोड़ें जो केवल ग्राहक ले सकते हैं।
आपकी सबसे अच्छी शर्त यह है कि एक नया बनाएं List<Customer>
, इसके माध्यम से पुनरावृत्त करें List<Object>
, प्रत्येक आइटम को नई सूची में जोड़ें, और उसे वापस लौटाएं।
जैसा कि दूसरों ने बताया है, आप उन्हें तुरंत नहीं डाल सकते, क्योंकि List<Object>
यह एक नहीं है List<Customer>
। आप क्या कर सकते हैं, उस सूची पर एक दृश्य को परिभाषित करना है जो इन-प्लेस प्रकार की जाँच करता है। Google संग्रह का उपयोग करना :
return Lists.transform(list, new Function<Object, Customer>() {
public Customer apply(Object from) {
if (from instanceof Customer) {
return (Customer)from;
}
return null; // or throw an exception, or do something else that makes sense.
}
});
ऊपर Bozho के साथ भी ऐसा ही है। आप इस विधि के माध्यम से यहाँ कुछ काम कर सकते हैं (हालाँकि मैं खुद इसे पसंद नहीं करता हूँ):
public <T> List<T> convert(List list, T t){
return list;
}
हाँ। यह आपकी सूची को आपके मांग वाले सामान्य प्रकार में डालेगा।
ऊपर दिए गए मामले में, आप कुछ इस तरह से कोड कर सकते हैं:
List<Object> list = getList();
return convert(list, new Customer());
सूची के साथ आप क्या करना चाहते हैं, इसके आधार पर, आपको इसे किसी को देने की आवश्यकता भी नहीं हो सकती है List<Customer>
। यदि आप केवल Customer
वस्तुओं को सूची में जोड़ना चाहते हैं , तो आप इसे निम्नानुसार घोषित कर सकते हैं:
...
List<Object> list = getList();
return (List<? super Customer>) list;
यह कानूनी है (ठीक है, न कि केवल कानूनी, लेकिन सही है - सूची "ग्राहक के लिए कुछ सुपरस्क्रिप्ट") है, और यदि आप इसे एक ऐसी विधि में पारित करने जा रहे हैं जो सूची में केवल वस्तुओं को जोड़ रही होगी तो ऊपर इसके लिए सामान्य सीमाएँ पर्याप्त हैं।
दूसरी ओर, यदि आप सूची से वस्तुओं को पुनः प्राप्त करना चाहते हैं और उन्हें ग्राहक के रूप में दृढ़ता से टाइप किया है - तो आप भाग्य से बाहर हैं, और ठीक ही ऐसा है। क्योंकि सूची है List<Object>
कि कोई गारंटी नहीं है कि सामग्री ग्राहक हैं, इसलिए आपको पुनर्प्राप्ति पर अपनी कास्टिंग प्रदान करनी होगी। (या वास्तव में, बिल्कुल, दोगुना यकीन है कि सूची में केवल शामिल होगा Customers
और दूसरे उत्तरों में से किसी एक से डबल-कास्ट का उपयोग करेगा , लेकिन यह महसूस करें कि आप संकलन-प्रकार-सुरक्षा को पूरी तरह से दरकिनार कर रहे हैं, जिसमें आप जेनरिक से प्राप्त करते हैं मामला)।
मोटे तौर पर यह कहना संभव है कि व्यापक संभव जेनेरिक सीमा पर विचार करना हमेशा अच्छा होता है जो एक विधि लिखते समय स्वीकार्य होगी, दोगुना इसलिए यदि यह लाइब्रेरी विधि के रूप में उपयोग होने वाला है। आप केवल एक सूची से पढ़ने के लिए जा रहे हैं, का उपयोग List<? extends T>
करने के बजाय List<T>
, उदाहरण के लिए - यह अपने कॉल करने देता है ज्यादा तर्क और इसका मतलब है कि वे कम संभावना है कि आप 'के समान परिहार्य मुद्दों में चलाने के लिए कर रहे हैं वे में पारित कर सकते हैं में अधिक गुंजाइश फिर से यहाँ हो रहा है