2010-10-19 23 views
7

के आसपास अजीब व्यवहार मैंने हाल ही में कोड के एक टुकड़े पर ठोकर खाई जो "ग्रहण" मुद्दे के कारण मेरे ग्रहण में संकलित नहीं होगा (this one के समान दिखता है)। कोड लिखने वाले लोगों ने मुझे आश्वासन दिया कि यह उनके स्थानीय पर्यावरण और उनके निरंतर एकीकरण में संकलित है और इसलिए मैंने इसे अनुकरण करने के लिए खेला। कार्यक्षेत्र डिफ़ॉल्ट के रूप में संकलित नहीं होगा और शिकायत करेगा कि विधि DoSomething (संग्रह) एक ही विलोपन DoSomething (संग्रह) है"समान मिटा" संकलन त्रुटि

package com.mycompany.playground; 

import java.util.ArrayList; 
import java.util.Collection; 

public class GenericsTest { 

    public static void main (String[] args) { 
     System.out.println(GenericsTest.doSomething(new ArrayList<A>())); 
     System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>())); 
    } 

    public GenericsTest() { 
    } 

    public static String doSomething(Collection<A> listOfA) { 
     return "has done something to Collection<A>"; 
    } 

    public static Integer doSomething(Collection<C> listOfC) { 
     return 0; 
    } 

    private class A { 

    } 

    private class C { 

    } 

} 

ग्रहण 1.6.0_21 JDK साथ Helios के रूप में:

इस स्निपेट पर एक नजर डालें जेनेरिकटेस्ट प्रकार में एक और तरीका। यह दूसरी विधि के बारे में भी यही कहेंगे।

ग्रहण को चलाने के लिए मजबूर करने की कोशिश की और देखा: धागे "मुख्य" java.lang.Error में अपवाद: अनसुलझा संकलन समस्या: विधि जेनरिक्सटेस्ट प्रकार में कुछ (संग्रह) तर्क (ArrayList) के लिए लागू नहीं है।

ठीक है। इसकी उम्मीद थी। अभी व। अगर मैं अपनी कमांड लाइन में जाता हूं और सरल चलाता हूं:

javac GenericsTest.java 

यह संकलित करता है। मैंने 1.6.0_21 और 1.6.0_06 (जिन लोगों के पास उनके वातावरण में था) की जांच की और न ही शिकायत की। मैंने क्लास फाइलों की प्रतिलिपि बनाई जहां एक्लिप्स ने उन्हें उम्मीद की और इसे फिर से चलाने के लिए मजबूर किया।

यह प्रिंट:

has done something to Collection<A> 
true 

अगर मैं बदलने के साथ

System.out.println(0 == GenericsTest.doSomething(new ArrayList<C>())); 

System.out.println(GenericsTest.doSomething(new ArrayList<C>())); 

यह अभी भी कमांड लाइन से बिना चेतावनी के संकलन, लेकिन एक ही "समाधान नहीं किया गया संकलन देना होगा समस्या "इसे चलाने की कोशिश करते समय।

यहां दो प्रश्न।

  • क्या जावा ने बस अंतर्निहित ग्रहण कंपाइलर को बाहर निकाला था? लगभग this previously asked question की तरह दिखता है, इसलिए मुझे विश्वास है कि मुझे जवाब पता है। (वैसे, मैं ग्रहण को javac का उपयोग करने के लिए कैसे कह सकता हूं?)।

  • क्यों javac चुपचाप संकलन होगा जावा तो साथ {0 ==} "संकेत" हटा चलाने के लिए असफल हो जायेगी (दूसरे परिदृश्य?

+0

ग्रहण कंपाइलर सही है, सूर्य 'जावैक' गलत है। जावा भाषा विशिष्टता ऐसा कहती है। विशेष रूप से, [धारा 8.1.2 जेनेरिक क्लासेस और टाइप पैरामीटर] (http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.2) इसमें एक सामान्य प्रकार क्या है और [ 8.4.2 विधि हस्ताक्षर] (http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.2) क्या हस्ताक्षर संकलित-समय त्रुटियों का कारण बनेंगे। – Powerlord

उत्तर

0

दोनों कोड के टुकड़े (के साथ या बिना 0 ==) मेरे ग्रहण में मेरे लिए काम करें। मैं एक्लिप्स 3.3.2 और जेडीके 1.6.0_21-बी07 का उपयोग कर रहा हूं जिसे ग्रहण के लिए "वैकल्पिक जेआरई" के रूप में कॉन्फ़िगर किया गया है। शायद यही कारण है कि यह मेरे लिए काम करता है।

1

यहां सवाल है: जब भी आपके पास 2 तरीके हों उसी नाम के साथ, उनके पास अलग हस्ताक्षर होना चाहिए।हस्ताक्षर यहाँ माना वापसी प्रकार शामिल नहीं है इसलिए इन दोनों तरीकों एक ही कक्षा

int foo(A a) 
float foo(A a) 

आप उदाहरण में में घोषित नहीं किया जा सकता है, तो आप अलग पैरामीटर प्रकार (Collection<A> और Collection<C>) के साथ दो विभिन्न तरीकों है, लेकिन आंतरिक रूप से, जब कंपाइलर अपने जादू करता है, जेनेरिक एआर संग्रह माना जाता है। यही "वही मिटा" का मतलब है।

मुझे अभी याद नहीं है अगर सभी जावा संस्करण इस व्यवहार को दिखाते हैं, क्योंकि मैं जावा 5 और जावा 6 के साथ बहुत अधिक अटक गया हूं।

आशा है कि यह सहायक हो सकता है।

+0

+1। "मुझे अभी याद नहीं है अगर सभी जावा संस्करण इस व्यवहार को दिखाते हैं, क्योंकि मैं जावा 5 और जावा 6 के साथ बहुत ज्यादा फंस गया हूं।" जावा 5 में जेनेरिक नए थे, इसलिए इससे पहले कोई फर्क नहीं पड़ता। मुझे यकीन है कि जावा 7 इस व्यवहार के साथ जारी रहेगा। – Powerlord

+0

सहमत हैं। बेशक जेनिक्स जावा 5 में नए थे, लेकिन मुझे पहले "उसी मिरर" को देखना याद है, लेकिन अब मैं अपने वर्तमान वातावरण में पावेल द्वारा प्रदान किए गए कोड के साथ इसे पुन: पेश नहीं कर सकता, इसलिए मैं सोच रहा था कि संकलक व्यवहार क्या हो सकता है जावा 5 और 6 से बदल गया है। AFAIK, जावा 5 जेनरिक में जहां पुराने कास्ट सिस्टम के आसपास कुछ वाक्य रचनात्मक चीनी, जावा 1.4 बाइनरी संगतता प्राप्त करने के लिए संकलन-समय में अनुवादित है, लेकिन मुझे यकीन नहीं है कि यह जावा 6 और आगामी के माध्यम से सच है या नहीं 7. लेकिन मुझे डर है कि मैं आध्यात्मिक प्रश्नों में डाइविंग कर रहा हूं;) – JorgeLC

1

पावेल, मुझे लगता है कि मैंने आपके द्वारा वर्णित एक ही मुद्दे का सामना किया है।

आज मैं अपने कोड के साथ हैकिंग कर रहा था और ग्रहण और जावा के कंपाइलरों के लिए एक ही अलग व्यवहार मिला। हालांकि, ऐसा लगता है कि यह एक ज्ञात संकलक मुद्दा है।

कृपया Bug 6182950 देखें।

धन्यवाद!

2

जावा विनिर्देश के अनुसार, दो तरीकों को हस्ताक्षर (नाम + पैरामीटर प्रकार) द्वारा अलग किया जाना चाहिए, वापसी प्रकार नहीं। और मूल कोड जेडीके http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6182950 में एक बग के कारण संकलित किया जा सकता है यह बग ग्रहण के कुछ संस्करणों में तय किया गया है, यही कारण है कि आप में से कुछ इसे ग्रहण में संकलित नहीं कर सकते हैं। क्यों संकलित कोड वास्तव में काम कर सकता है, आपको समझना चाहिए कि जावा भाषा JVM बाइट कोड के बराबर नहीं है। बाइट कोड में आपके पास बहुत सारे अवैध जावा नाम हो सकते हैं और हां, बाइट कोड हस्ताक्षर, वापसी प्रकार, और शायद कुछ अतिरिक्त जानकारी के तरीकों को अलग करता है।

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