2010-07-15 20 views
7

संभव डुप्लिकेट:
Is this valid Java?फ़ीचर या बग: यह जावा कोड संकलित क्यों करता है?

मैं compiles नीचे जावा वर्ग को खोजने के लिए आश्चर्य हुआ। इसमें एक ही नाम, तर्कों की संख्या और तर्क के निम्नलिखित प्रकार-प्रकार के प्रकार के साथ कई विधियां हैं। फिर भी, यह सूर्य जेडीके 1.6 कंपाइलर के विभिन्न संस्करणों का उपयोग कर विंडोज़ पर अपेक्षित रूप से संकलित और काम करता है। तो यह उम्र के लिए चारों ओर हो गया है, तो यह एक बग है है ....

यह भी ग्रहण के कई संस्करण के साथ तैयार की है, लेकिन संकलक साथ संकलक यह नहीं है कि ग्रहण 3.6

साथ जहाजों अलावा कोड बुला में अपेक्षित काम करता है - यानी। कॉलिंग कोड पर महत्वाकांक्षी विधियों के बारे में कोई त्रुटि नहीं है।

आप तरीकों ErasureExample.class.getMethods() वे सभी उपस्थित हैं .....

JLS के अनुसार यह गैरकानूनी हो सकता है अगर तरीकों "ओवरराइड-बराबर" हस्ताक्षर द्वारा लौटाए से अधिक पुनरावृति हैं - सख्ती से वे नहीं करते हैं, क्योंकि संग्रह, संग्रह और संग्रह में से कोई भी समकक्ष ओवरराइड नहीं है .... यदि ऐसा है तो ग्रहण गलत है, जेडीके सही है ...

फ़ीचर या बग? इसे संकलित करना चाहिए?

/** 
* Demonstrates that a class with methods that differ only by return type can exist. 
* Section 8.4 of the JLS suggests this is an error IFF the methods had 
* override equivalent signatures, which they dont'' 
* 
* 
* From JLS 8.4... 

* It is a compile-time error for the body of a class to declare as members two methods 
* with override-equivalent signatures (§8.4.2) (name, number of parameters, and types 
* of any parameters). 
* 
* Should it compile? 
*/ 
public class ErasureExample { 
    // note the single Collection<Integer> argument... 
    public static int[] asArray(Collection<Integer> vals) { 
     if (vals == null) 
     return null; 

     int idx = 0; 
     int[] arr = new int[vals.size()]; 
     for (Integer i : vals) { 
     arr[idx] = i==null? 0 : i.intValue(); 
     idx++; 
     } 
     return arr; 
    } 

    // same method name as above, type differs only by generics.... surely this violates 8.4 of JLS... 
    public static long[] asArray(Collection<Long> vals) { 
     if (vals == null) 
     return null; 

     int idx = 0; 
     long[] arr = new long[vals.size()]; 
     for (Long i : vals) { 
     arr[idx] = i==null? 0 : i.longValue(); 
     idx++; 
     } 
     return arr; 
    } 

    // same method name as above, type differs only by generics.... surely this violates 8.4 of JLS... 
    public static boolean[] asArray(Collection<Boolean> vals) { 
     if (vals == null) 
     return null; 

     int idx = 0; 
     boolean[] arr = new boolean[vals.size()]; 
     for (Boolean b : vals) { 
     arr[idx] = b==null? false : b.booleanValue(); 
     idx++; 
     } 
     return arr; 
    } 

} 

उत्तर

-3

इन विधियों में बिल्कुल समान हस्ताक्षर नहीं हैं। विभिन्न वापसी मूल्य और विभिन्न पैरामीटर प्रकार। हां वास्तव में, जेनेरिक एक बड़ा अंतर बनाते हैं। सब कुछ अच्छा दिखता है।

+7

सुधार: वापसी मूल्य हस्ताक्षर का हिस्सा नहीं है – schar

+5

दरअसल, बाइटकोड स्तर पर, विधि वर्णनकर्ताओं में रिटर्न प्रकार भी होता है, और इनके बीच अंतर करने के लिए उपयोग किया जा सकता है। कंपाइलर कभी-कभी उस परिणाम का लाभ उठा सकता है, जिससे आप परिणाम को सहेजने वाले चर के प्रकार की जांच कर सकते हैं, क्योंकि संकलक बता सकता है कि किस विधि को बुलाया जाना चाहिए, और बाइटकोड में यह केवल निर्देशक के साथ निर्देश 'कॉल विधि है- और- उस'। विनिर्देशों के अनुसार, यह बिल्कुल सही नहीं है, लेकिन संकलक अब इसके लिए अनुमति देता है। जाहिर है जावा 7 में वे इसे बदल सकते हैं। –

+1

इस कोड के साथ थोड़ा सा खेलने के बाद, मुझे एंड्री फियरबिनटेनु की सबसे अधिक भरोसेमंद स्पष्टीकरण मिलता है। समान हस्ताक्षर के साथ संकलन विधियों के साथ कोई व्यावहारिक समस्या नहीं है, क्योंकि बाइटकोड में कॉल विधियों के अद्वितीय संख्यात्मक आईडी पर आधारित हैं। कुछ कंपाइलर्स इस तथ्य का लाभ उठाते हैं कि इसे संभव बनाने के लिए उनके पास सामान्य जानकारी है। इससे समस्याएं आती हैं। उदाहरण के लिए देखें प्रतिबिंब के साथ क्या होता है: ErasureExample.class.getDeclaredMethod ("asArray", Collection.class) स्रोत कोड में पहली विधि देता है! (यानी कोड को बदलकर कोड बदलता है) –

2

कंपाइलर संकलन-समय पर विधियों को असंबद्ध करने के लिए पर्याप्त स्मार्ट है, हालांकि अंत में यह टाइप एरर करता है। जनरेटिंग जेनरिक्स का पूरा बिंदु एक संकलन-समय प्रकार सुरक्षा जांच प्रदान करना है, टाइप मिरर केवल एक कार्यान्वयन विवरण है।

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