2015-03-02 5 views
19

मैं एंड्रॉइड स्टूडियो 1.1.0 का उपयोग कर रहा हूं।अनचेक असाइनमेंट चेतावनी

public static class A { 
    public Map<Integer, String> getMap() { 
     return null; 
    } 
} 

public static class B { 
    public void processA(A a) { 
     Map<Integer, String> map = a.getMap(); 
    } 
} 

लेकिन बनाने A सामान्य:

public static class A<T> { 
    public Map<Integer, String> getMap() { 
     return null; 
    } 
} 

और इस लाइन:

यह कोई चेतावनी का कारण बनता है

Map<Integer, String> map = a.getMap(); 

अब आप एक चेतावनी हो जाता है: "Unchecked assignment: 'java.util.Map to java.util.Map<java.lang.Integer, java.lang.String>'

भले ही getMap का हस्ताक्षर T से पूरी तरह से स्वतंत्र है, और कोड Map के प्रकारों के बारे में स्पष्ट नहीं है।

मुझे पता है कि मैं processA reimplementing इस प्रकार से चेतावनी से छुटकारा पाने के कर सकते हैं:

public <T> void processA(A<T> a) { 
    Map<Integer, String> map = a.getMap(); 
} 

लेकिन मैं ऐसा करने के लिए होगा? T क्या मायने रखता है?

तो, सवाल है - क्यों विलोपन टाइप करता है न केवल T को प्रभावित करने के लिए है (जो समझा जा सकता है - अगर मैं A का एक उदाहरण गुजर रहा हूँ, T एक अज्ञात है), लेकिन यह भी "हार्डकोडेड" <Integer, String> की तरह सामान्य हस्ताक्षर इस मामले में?

उत्तर

13

अपने दूसरे मामले में जब आप कार्य करें:

public void processA(A a) 

आप A से क्या मतलब है? क्या इसका मतलब A<String> या A<List<String>> या क्या है? हो सकता है कि आप A के प्रकार से संबंधित किसी भी चीज़ का उपयोग न करें, लेकिन हे कंपाइलर इस तथ्य को नहीं जानता है। कंपाइलर के लिए, बस A आतंक का संकेत है।

आपके मामले में, क्योंकि आप विशेष रूप से न एक के प्रकार पता करने की जरूरत है, तो आप कर सकते हैं:

public void processA(A<?> a) { 
    Map<Integer, String> map = a.getMap(); 
} 

A<?> साधनों का एक तर्क प्रकार के बाद, आप विशेष रूप से A के प्रकार की परवाह नहीं करते और सिर्फ निर्दिष्ट एक जंगली कार्ड आपके लिए इसका मतलब है: A का कोई भी ऑब्जेक्ट इसके सामान्य प्रकार के रूप में किसी भी प्रकार के साथ करेगा। हकीकत में, इसका मतलब है कि आप इस प्रकार को नहीं जानते हैं। इसका बेकार है क्योंकि आप A से संबंधित कुछ भी नहीं कर सकते हैं ? वस्तुतः कुछ भी हो सकता है!

लेकिन अपने विधि शरीर के अनुसार, यह दुनिया में सभी समझ में आता है A<?> उपयोग करने के लिए है क्योंकि शरीर में कोई जहाँ आप वास्तव में `आप एक के प्रकार से संबंधित कुछ भी उपयोग नहीं कर रहा हो सकता है A

+0

के प्रकार की जरूरत है , लेकिन हे कंपाइलर इस तथ्य को नहीं जानता है - ठीक है, यह * इसे आसानी से जान सकता है, बस 'प्रक्रिया ए' के ​​कार्यान्वयन पर नज़र डालें, यह सत्यापित करना मुश्किल नहीं है कि 'टी' अप्रासंगिक है;) जैसा कि आप सुझाव देते हैं, मैं ' 'के साथ जाऊंगा, लेकिन मैं कंपाइलर से निराश हूं। –

+0

@ कोनराडमोराव्स्की एक आदर्श दुनिया में, केवल 'ए' अवैध होना चाहिए और कोड संकलित नहीं होना चाहिए। लेकिन पिछड़े संगतता कारणों के लिए इसकी अनुमति है। 'ए ' के रूप में घोषित कक्षा के लिए, इसका सामान्य प्रकार 'ए' से संबंधित कुछ भी करने के लिए बेहद महत्वपूर्ण है। तो बस 'ए' का उपयोग करने की अनुमति नहीं दी जानी चाहिए (वास्तव में स्कैला में, केवल 'ए'' का उपयोग करना अवैध है) – Jatin

+0

हाँ, मुझे कल्पना है ... मैं स्कैला का उपयोग नहीं करता, लेकिन मैं सी # पक्ष से आया हूं दुनिया और जावा के जेनेरिक जूते पहनने की तरह लगता है। –

5

जब आप किसी भी संभावित प्रकार T के A<T> स्वीकार करने के लिए मतलब है, लेकिन T की जरूरत नहीं है, यह सही ढंग से एक वाइल्ड कार्ड का उपयोग और A<?> लिख कर व्यक्त की है। ऐसा करने से आपके कोड में चेतावनी से छुटकारा मिल जाएगा:

public void processA(A<?> a) { 
    Map<Integer, String> map = a.getMap(); 
} 

नंगे प्रकार A समतुल्य रूप इलाज नहीं है का उपयोग करना। के रूप में Java Language Specification में बताया गया है, कि जैसे कच्चे प्रकार के नए कोड में इस्तेमाल किया जा करने का इरादा नहीं कर रहे हैं:

अनियंत्रित रूपांतरण विरासत कोड का एक चिकनी अंतर्संचालन, सामान्य प्रकार की शुरूआत से पहले लिखा पुस्तकालयों के साथ, सक्षम करने के लिए प्रयोग किया जाता है कि जेनेरिकिटी (एक प्रक्रिया जिसे हम जनरेशन कहते हैं) का उपयोग करने के लिए एक रूपांतरण किया है। ऐसी परिस्थितियों में (सबसे विशेष रूप से, java.util में संग्रह फ्रेमवर्क के ग्राहक), विरासत कोड कच्चे प्रकार का उपयोग करता है (उदाहरण के लिए संग्रह < स्ट्रिंग > के बजाय संग्रह)। कच्चे प्रकार के अभिव्यक्तियों को पुस्तकालय विधियों के तर्क के रूप में पारित किया जाता है जो उनके समान औपचारिक मानकों के प्रकार के समान पैरामीटर संस्करणों का उपयोग करते हैं।

ऐसे कॉल जेनिक्स का उपयोग कर सिस्टम सिस्टम के तहत स्थिर रूप से सुरक्षित नहीं दिखाए जा सकते हैं। ऐसी कॉल को अस्वीकार करने से मौजूदा कोड के बड़े निकायों को अमान्य कर दिया जाएगा, और उन्हें पुस्तकालयों के नए संस्करणों का उपयोग करने से रोक दिया जाएगा। बदले में, लाइब्रेरी विक्रेताओं को सामान्यता का लाभ उठाने से हतोत्साहित किया जाएगा। घटनाओं के इस तरह के अवांछित मोड़ को रोकने के लिए, कच्चे प्रकार को सामान्य प्रकार की घोषणा के मनमाने ढंग से आमंत्रण में परिवर्तित किया जा सकता है, जिसमें कच्चे प्रकार का संदर्भ होता है। जबकि रूपांतरण बेकार है, इसे व्यावहारिकता के लिए रियायत के रूप में सहन किया जाता है। ऐसे मामलों में एक अनचेक चेतावनी जारी की जाती है।

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