2015-06-24 7 views
6

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

public class GenericOptional<T> { 

    public GenericOptional(T someValue) {} 

    public T getValue() { return null; } 

    public Optional<String> getOptionalString() { return Optional.empty(); } 
} 

क्या मैं जोर देना चाहते है कि वापसी प्रकार विधि getOptionalString()प्रकार पैरामीटरT पर निर्भर नहीं करता की Optional<String>

अब जावा 8u45 का उपयोग कर निम्नलिखित कोड है, जो अंदर ग्रहण लूना 4.4.2 संकलित हो जाता है पर एक नजर है:

public static void main(String[] args) { 
    Object obj = new GenericOptional<>(Boolean.TRUE); 
    GenericOptional go = (GenericOptional) obj; 
    Optional os = go.getOptionalString(); 
} 

स्थानीय चर ostype- बिना प्रकार Optional है पैरामीटरString! ग्रहण कंपाइलर ने निश्चित टाइप-पैरामीटर के बारे में जानकारी खो दी है। क्या किसी को पता है क्यों?

अब एक दूसरे कोड उदाहरण देखें:

public static void main(String[] args) { 
    Object obj = new GenericOptional<>(Boolean.TRUE); 
    GenericOptional<?> go = (GenericOptional) obj; 
    Optional<String> os = go.getOptionalString(); 
} 

विधि getOptionalString() की वापसी प्रकार GenericOptional<?> के रूप में स्थानीय चर go घोषित करने से अब Optional<String> है अपेक्षा के अनुरूप।

कोई भी इस व्यवहार को समझा सकता है?

उत्तर

4

आप raw types के व्यवहार का सामना कर रहे। जब आप कच्चे प्रकार का उपयोग कर रहे हैं, तो जेनेरिक प्रभावी रूप से पूरी तरह से बंद कर दिया गया है, इस पर ध्यान दिए बिना कि सदस्य के सामान्य हस्ताक्षर और कक्षा के प्रकार पैरामीटर के बीच कोई संबंध है या नहीं।

इसके पीछे तर्क यह है कि कच्चे प्रकार केवल पूर्व-जेनेरिक कोड के साथ पिछड़े संगतता की सुविधा है। तो या तो आपके पास जेनेरिक है या आप नहीं करते हैं।

GenericOptional<?> go = (GenericOptional<?>) obj; 
Optional<String> os = go.getOptionalString(); 

<?> का उपयोग का तात्पर्य "मैं वास्तविक प्रकार पैरामीटर पता नहीं है और मैं डॉन:

जेनेरिक विधि वर्ग की वास्तविक प्रकार पैरामीटर पर निर्भर नहीं करता है, तो इस समस्या को ठीक करने के लिए आसान है परवाह नहीं है लेकिन मैं सामान्य प्रकार की जांच का उपयोग कर रहा हूं "।

+0

उत्तर के लिए धन्यवाद। कोको ने वही जवाब दिया और मुझे नहीं पता कि आपको सही/सर्वोत्तम अनुमोदन दोनों कैसे देना है। इसलिए इस तथ्य के कारण कि आपने पहले प्रश्न का उत्तर दिया था, यहां तक ​​कि आपने अपनी स्पष्टीकरण का समर्थन करने के लिए उदाहरण कोड प्रदान नहीं किया है, मैं आपको "सबसे सहायक" अनुमोदन दूंगा। अगर आपको लगता है कि कोको का जवाब उन लोगों के लिए अधिक मूल्यवान है जो जानना चाहते हैं कि यह कैसे काम करता है, तो मुझे नहीं दें और मैं कोको को "सबसे उपयोगी" अनुमोदन स्थानांतरित कर दूंगा। – Harmlezz

4

यह ग्रहण या कुछ भी नहीं, बल्कि कच्चे प्रकार के बारे में है। ,

public static void main(String[] args) { 
    Object obj = new GenericOptional<>(Boolean.TRUE); 
    GenericOptional go = (GenericOptional) obj; 
    Optional os = go.getOptionalString(); 
} 

यहाँ आप GenericOptional के कच्चे उदाहरण है, जिसका अर्थ है कि प्रकार पैरामीटर जानकारी पूरी तरह से बंद कर दिया जाएगा बना रहे हैं:

के इस स्निपेट की समीक्षा करें। तो, instantiating एक कच्चेGenericOptional मतलब यह है कि उदाहरण के रूप में निम्नलिखित तरीकों का खुलासा होगा: अब हम दूसरे टुकड़ा

public static void main(String[] args) { 
    Object obj = new GenericOptional<>(Boolean.TRUE); 
    GenericOptional<?> go = (GenericOptional) obj; 
    Optional<String> os = go.getOptionalString(); 
} 

हम देख सकते हैं कि आप कर रहे हैं की समीक्षा करते हैं

public class GenericOptional { 

    public GenericOptional(Object someValue) {} 

    public Object getValue() { return null; } 

    public Optional getOptionalString() { return Optional.empty(); } 
} 

हालांकि, GenericOptional का एक सामान्य उदाहरण। यहां तक ​​कि इसे टाइप पैरामीटर <?> है, संकलक बारी बंद नहीं के बारे में प्रकार-पैरामीटर देखभाल, तो उदाहरण getOptionalString() विधि पैरामिट्रीकृत सामने आ जाएगी, इस तरह:

public Optional<String> getOptionalString() { return Optional.empty(); } 
+0

अच्छा स्पष्टीकरण के लिए आपको कोको धन्यवाद। कृपया टिप्पणी को मैंने होल्गर के उत्तर में जोड़ा, मैंने उसे "सबसे सहायक" अनुमोदन देने के लिए क्यों कहा। आशा है कि आप इस फैसले से ठीक हैं। – Harmlezz

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