2008-11-24 16 views
9

मैं इस जावा जेनेरिक कास्ट कैसे बना सकता हूं?मैं इस जावा जेनेरिक कास्ट कैसे बना सकता हूं?

public interface IField { 

} 


class Field implements IField { // package private class 

} 

public class Form { 
    private List<Field> fields; 


    public List<IField> getFields() { 
    return this.fields; 

    } 

} 

वापसी कथन एक संकलक त्रुटि (मैं कारण पता है - मैंने पढ़ा जेनरिक ट्यूटोरियल) फेंकता है, लेकिन यह इस तरह के कोड लिखने के लिए बहुत आसान हो जाएगा।

यदि मैंने सूची के रूप में "फ़ील्ड" घोषित किया है तो मुझे फॉर्म क्लास के अन्य तरीकों में फ़ील्ड में कई सारे क्षेत्रों का उपयोग करने की आवश्यकता होगी।

क्या मैं उस हानिकारक कंपाइलर को अपने नियमों को झुकाव और उस वापसी विवरण को संकलित करने के लिए मजबूर कर सकता हूं?

अग्रिम धन्यवाद।

+0

एक तरफ ध्यान दें के रूप में, this.fields this.fiedls रूप typoed है और मैं संपादित करने के लिए एक पर्याप्त उच्च प्रतिनिधि की जरूरत नहीं है अन्य लोगों की पोस्ट। – Powerlord

+0

@ आर बेमेरोस - निश्चित, धन्यवाद। –

उत्तर

17

एक बेहतर समाधान है, IMO, एक घिरे वाइल्डकार्ड का उपयोग करने के लिए अपने विधि के हस्ताक्षर बदलने के लिए है:,

public List<? extends IField> getFields() 

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

+1

इस दृष्टिकोण का नकारात्मक पक्ष यह है कि यह कॉलर को वाइल्डकार्ड को संभालने के लिए मजबूर करता है। एक सामान्य सिद्धांत के रूप में मैं सुझाव दूंगा (और आईआईआरसी जेनेरिक लेखकों ने सुझाव दिया है) केवल विधि पैरामीटर पर वाइल्डकार्ड का उपयोग करके, और उन्हें रिटर्न प्रकारों से परहेज करना। – JodaStephen

+0

यह उपयोग के मामले, आईएमओ पर निर्भर करता है। यदि विचार यह है कि यह वास्तव में पढ़ने के लिए सिर्फ एक संग्रह है, वाइल्डकार्ड समझ में आता है (और वास्तव में क्या उपलब्ध है व्यक्त करता है)। यदि यह लिखने योग्य भी है, तो यह स्पष्ट रूप से काम नहीं करेगा - और वास्तव में नहीं करना चाहिए। –

+0

क्या यू इस प्रश्न को देख सकता है? http://stackoverflow.com/questions/314203/overidin-methods-by-return-type-in-java –

12

जैसा भी होता है, आप कर सकते हैं, क्योंकि जावा जेनरिक सिर्फ टाइप सिस्टम के हिस्से पर नहीं बने हैं।

आप

return (List<IField>)(Object)this.fields; 

कर सकते हैं, क्योंकि सभी List<T> वस्तुओं अंतर्निहित समान प्रकार हैं।

ध्यान रखें कि इससे किसी को भी आपकी सूची में IField लागू करने की अनुमति मिलती है, इसलिए यदि आपका संग्रह केवल पढ़ने के लिए नहीं है, तो आप कठिनाइयों में भाग ले सकते हैं।

+0

मैं इसे केवल पाठ्यक्रम में पढ़ूंगा - धन्यवाद यू –

0

सूरज की रोशनी सही है, आप इसे केवल कास्ट कर सकते हैं।

एक और ठीक है कि आप वास्तव में एक List<Field> जरूरत है, या आप List<IField> के लिए अपने आंतरिक fields चर बदल सकते हैं कि फिर से जांच कर रहा है।

जब तक आप IField इंटरफ़ेस पर मौजूद सूची की सामग्री पर केवल विधियों का उपयोग करते हैं, तो आप एक स्ट्रेटफोर्डवर्ड स्वैप करने में सक्षम होना चाहिए।

5

ऐसा मत करो।

List<Field>List<IField> नहीं है। आप संकलक को स्वीकार करने के लिए मजबूर करने की कोशिश कर सकते हैं (मैंने सोचा कि यह संभव नहीं था, मेरी इच्छा है कि यह संभव नहीं था), लेकिन इससे आपको परेशानी होगी। कंपाइलर उपयोगकर्ता को आईफिल्ड से प्राप्त आविष्कार को आपके आविष्कारों को तोड़ने और जेनरिक्स प्रदान करने वाली प्रकार की सुरक्षा में तोड़ने की अनुमति देगा। बाद में List<Field> का उपयोग टूट जाएगा क्योंकि अजीब तत्व का निष्कर्षण उस क्षेत्र में अंतर्निहित कास्ट विफल हो जाएगा जहां आप इसकी अपेक्षा नहीं करेंगे।

यदि आपको List<Field> के बजाय List<IField> वापस करने की आवश्यकता है, तो मैं एक ही तत्व से भरी एक नई सूची उत्पन्न करने की अनुशंसा करूंगा। यदि आप अपने इंटरफ़ेस को Jon Skeets समाधान के लिए संशोधित कर सकते हैं।

2

कॉलर सूची संशोधित करने में सक्षम होने की जरूरत नहीं होती है, तो:

return Collections.<IField>unmodifiableList(this.fields); 
संबंधित मुद्दे