2011-08-14 11 views
9

के माध्यम से संकलन नहीं मैं निम्नलिखित संरचना है:इंटरफ़ेस में covariant वापसी प्रकार javac

public interface BarReturn {} 
public interface FooReturn {} 
public interface FooBarReturn extends FooReturn, BarReturn {} 

public interface Foo { 
    FooReturn fooBar(); 
} 

public interface Bar { 
    BarReturn fooBar(); 
} 

public interface FooBar extends Foo, Bar { 
    FooBarReturn fooBar(); 
} 

javac निम्न संदेश के साथ विफल रहता है:

FooBar.java:2: types Bar and Foo are incompatible; both define fooBar(), but with unrelated return types 
public interface FooBar extends Foo, Bar { 
    ^
1 error 

हालांकि, ग्रहण यह ठीक संकलन कर सकते हैं, और जहाँ तक जैसा कि मैं देख सकता हूं कि इसे संकलित करना चाहिए - FooBar की fooBar() विधि कॉन्वेंट रिटर्न का उपयोग करके Foo और Bar की fooBar() विधि दोनों के अनुबंध को संतुष्ट करती है।

क्या यह एक्लिप्स संकलन में या जावा में एक बग है? या क्या इसे संकलित करने के लिए जावैक को मनाने का कोई तरीका है? संदर्भ के लिए मेरे जावैक विकल्प इस तरह दिखते हैं:

javac -d /tmp/covariant/target/classes -sourcepath /tmp/covariant/src/main/java: /tmp/covariant/src/main/java/Foo.java /tmp/covariant/src/main/java/BarReturn.java /tmp/covariant/src/main/java/FooBarReturn.java /tmp/covariant/src/main/java/Bar.java /tmp/covariant/src/main/java/FooReturn.java /tmp/covariant/src/main/java/FooBar.java -g -nowarn -target 1.6 -source 1.6 
+0

ओपन-जेडीके कंपाइलर संस्करण 1.6.0_22 के साथ एक ही समस्या। लेकिन यह जावा 7 में काम करता है। –

+0

बस इसका परीक्षण किया और हाँ, तो यह करता है - बढ़िया। –

+0

संभावित [डुप्लिकेट] (http://stackoverflow.com/questions/11343238/java-implementing-multiple-interfaces-with-same-method-and-different-return-ty)? – amaidment

उत्तर

3

आप अपने FooBar इंटरफ़ेस में Foo और Bar दोनों को विस्तारित कर रहे हैं। इस तरह आप असंगत रिटर्न प्रकारों के साथ दो विधियों को विरासत में ले रहे हैं। जावा सह-भिन्नता केवल तिलकोव प्रतिस्थापन के बाद ही अनुमति दी जाती है। उर्फ, ओवरराइडिंग उम्मीदवारों के प्रकार को ओवरराइड रिटर्न प्रकार का उप-वर्ग होना चाहिए।

इस चाहिए संकलन की तरह कुछ के ऊपर अपने उदाहरण में:

public interface BarReturn {} 
public interface FooReturn {} 
public interface FooBarReturn extends FooReturn, BarReturn {} 

public interface Foo { 
    FooReturn fooBar(); 
} 

public interface FooBar extends Foo{ 
    FooBarReturn fooBar(); 
} 
+0

ओपी के कोड में, ओवरराइडिंग विधि का रिटर्न प्रकार * * ओवरराइड विधियों के रिटर्न प्रकारों को उप-प्रकार करता है। तो अकादमिक दृष्टिकोण से, ओपी का कोड मान्य नहीं होने का कोई कारण नहीं है। –

1

The JLS (§9.4.1) का कहना है:

यह एक अंतरफलक ओवरराइड-बराबर हस्ताक्षरों के साथ कई तरीकों के वारिस के लिए संभव है (§ 8.4.2)। ऐसी स्थिति में स्वयं संकलित-समय त्रुटि का कारण नहीं बनती है। इंटरफेस को पर सभी विधियों का वारिस माना जाता है। हालांकि, विरासत विधियों में से एक को किसी भी अन्य विरासत विधि के लिए प्रतिस्थापन योग्य होना चाहिए; अन्यथा, एक संकलन समय त्रुटि तब होती है (दॅ खंड इस मामले में नहीं कारण त्रुटियों कर फेंकता है।)

तो मैं कहूँगा कि javac सही है। लेकिन यह मेरे लिए वकील शब्दकोष की तरह दिखता है, इसलिए मैं गलत हो सकता था।

1

इस javaranch discussion में एक उत्तर यह सुझाव देता है कि यह एक जैविक बग है। हालांकि, संदर्भित bug url काम नहीं कर रहा है।

+0

ऐसा लगता है [जेडीके -7u4] (http://www.oracle।कॉम/टेक्नवर्क/जावा/जावा/डाउनलोड/जेडीके -7यू 4-डाउनलोड -15 91156.html) बग को हल करता है। – Georg

1

समाधान के लिए, आप

interface Foo1 extends Foo { 
    FooBarReturn fooBar(); 
} 
interface Bar1 extends Bar { 
    FooBarReturn fooBar(); 
} 
public interface FooBar extends Foo1, Bar1 { } 

सुंदर नहीं कर सकता है, लेकिन चाल करना चाहिए।

+1

धन्यवाद, यह एक अच्छा विचार है - हालांकि, क्योंकि यह ओपनजेडीके 7 के जावैक के साथ संकलित करता है और ग्रहण कंपाइलर के साथ मैं अतिरिक्त प्रकार के परिचय के बिना इसके आसपास काम कर सकता हूं। –

+1

यह काम नहीं कर रहा है, jdk6 का javac अभी भी कहता है 'प्रकार Bar1 और Foo1 असंगत हैं; दोनों fooBar() को परिभाषित करते हैं, लेकिन असंबद्ध रिटर्न प्रकारों के साथ। –

1

मुझे एक ही समस्या थी और ओरेकल से जेडीके 7 का उपयोग करके यह ठीक लगता है।

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