2013-11-01 10 views
5

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

निम्न कोड जो मैं काम कर रहा हूं उसका एक अलग संस्करण है। जिस लाइन पर मैं अपना 'test3 प्रबंधक' बनाने का प्रयास करता हूं, संकलित नहीं होगा और मैं यह समझने की कोशिश कर रहा हूं कि ऐसा क्यों है। इसके नीचे की रेखाएं 'वर्कअराउंड' दिखाती हैं, जिसे मैं टालने की कोशिश कर रहा हूं।

import java.util.List; 

    public class GenTest { 
     public static void main(String[] args) { 
      String test1 = ""; 
      IRandomType<String> test2 = null; 
      IAnotherRandomType<?> test3 = null; 

      IManager<String> test1Manager = Factory.createManager(test1); 
      IManager<IRandomType<String>> test2Manager = Factory.createManager(test2); 
      IManager<IAnotherRandomType<?>> test3Manager = Factory.createManager(test3); // Doesn't compile. Why? 

      // Work around? 
      IManager<?> test3ManagerTmp = Factory.createManager(test3); 
      IManager<IAnotherRandomType<?>> test3Manager2 = (IManager<IAnotherRandomType<?>>) test3ManagerTmp; 
     } 

     public interface IRandomType<T> {} 
     public interface IAnotherRandomType<T> {} 
     public interface IManager<T> {} 

     public static class Factory { 
      public static <T> IManager<T> createManager(T object) { 
       return null; 
      } 
     } 
    } 

सटीक संकलन त्रुटि संदेश है:

Type mismatch: cannot convert from GenTest.IManager<GenTest.IAnotherRandomType<capture#1-of ?>> to GenTest.IManager<GenTest.IAnotherRandomType<?>> 

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

संबंधित प्रश्न हैं: निम्नलिखित

उत्तर

3

उपयोग:

IManager<IAnotherRandomType<?>> test3Manager = 
     Factory.<IAnotherRandomType<?>>createManager(test3); 

यह सिर्फ संकलक के प्रकार निष्कर्ष के एक मामले पर गिर रही है इसका चेहरा, इसलिए यह स्पष्ट रूप से प्रकार तर्क प्रदान करना आवश्यक है T के लिए ent।

अधिक तकनीकी रूप से:

test3 प्रकार IAnotherRandomType<?>, जहां ? एक वाइल्डकार्ड कब्जा है के लिए घोषित किया जाता है - एक-उपयोग प्रकार पैरामीटर कुछ विशिष्ट अज्ञात प्रकार का प्रतिनिधित्व करने का एक तरह। यह संकलक का संदर्भ है जब यह capture#1-of ? कहता है। जब आप test3 को createManager में पास करते हैं, TIAnotherRandomType<capture#1-of ?> के रूप में अनुमानित हो जाता है।

इस बीच, test3Manager प्रकार IManager<IAnotherRandomType<?>> है, जो एक नेस्टेड वाइल्डकार्ड है के लिए घोषित किया जाता है - यह एक प्रकार पैरामीटर की तरह व्यवहार नहीं होता है बल्कि किसी भी प्रकार प्रतिनिधित्व करता है।

जेनेरिक aren't covariant के बाद से, कंपाइलर IManager<IAnotherRandomType<capture#1-of ?>> से IManager<IAnotherRandomType<?>> में परिवर्तित नहीं हो सकता है।नेस्टेड वाइल्डकार्ड पर

अधिक पढ़ने:

+0

+1 बस एक संपादित की जरूरत - 'T' के रूप में # 1-' IAnotherRandomType <कब्जा अनुमान लगाया जाता है का? '', न केवल 'कैप्चर # 1-का?' –

+0

क्या (अनुपस्थिति) वास्तव में यहां प्रासंगिक है? 'कैप्चर # 1-ऑफ' और '?' असंबद्ध नहीं हैं? – mpartel

+0

@ रोहितजैन अच्छा पकड़ - तय। –

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