मैंने जावा के जेनेरिक में एक समस्या में भाग लिया है जिसमें एक ही कोड संकलित और जावा 6 में ठीक काम करेगा, लेकिन जावा में उसी मिरर के कारण संकलित करने में विफल रहेगाजेनेरिक विधियों को अधिभारित करते समय जावा 5 और 6 के बीच अलग व्यवहार
import java.util.ArrayList;
import java.util.List;
public class TestErasure {
public static Object method(List<Object> list) {
System.out.println("method(List<Object> list)");
return null;
}
public static String method(List<String> list) {
System.out.println("method(List<String> list)");
return null;
}
public static void main(String[] args) {
method(new ArrayList<Object>());
method(new ArrayList<String>());
}
}
जावा 5 में, मैं हुए कहा कि "विधि" का विलोपन में ही है उम्मीद संकलन त्रुटि मिलती है,: 5. मैं एक फ़ाइल TestErasure.java एक ओवरलोड विधि है, जिसे "विधि" है:
$ javac -version
javac 1.5.0_19
$ javac TestErasure.java
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
public static String method(List<String> list) {
^
TestErasure.java:17: method(java.util.List<java.lang.Object>) in TestErasure cannot be applied to (java.util.ArrayList<java.lang.String>)
method(new ArrayList<String>());
^
2 errors
हालांकि, जावा 6 इस कोड को संकलित और चलाने में सक्षम है।
$ javac -version
javac 1.6.0_16
$ javac TestErasure.java
$ java TestErasure
method(List<Object> list)
method(List<String> list)
मिटाया की मेरी वर्तमान समझ के आधार पर (धन्यवाद Jon Skeet और Angelika Langer के लिए), मैं वास्तव में संकलन त्रुटि के रूप में जावा 5 द्वारा फेंका उम्मीद (जब तक कि कुछ में कैसे जावा जेनेरिक्स संभाला बदल गया है - जो मैं पर नहीं मिल सकता है जावा 6 रिलीज नोट्स)। वास्तव में, यदि मैं अतिभारित तरीकों में से एक की वापसी प्रकार संशोधित:
public static Object method(List<Object> list) ...
public static Object method(List<String> list) ...
जावा 6 इसलिए भी कि एक ही मिटाया का संकलन करने में विफल रहता है:
$ javac TestErasure.java TestErasure.java:5: name clash: method(java.util.List<java.lang.Object>) and method(java.util.List<java.lang.String>) have the same erasure
public static Object method(List<Object> list) {
^
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
public static Object method(List<String> list) {
^
2 errors
ऐसा लगता है कि में वापसी प्रकार जावा 6 किसी भी तरह से उपयोग करने के लिए किस अधिभारित विधि के चयन को प्रभावित करता है?
क्या कोई व्यक्ति जावा 6 में पहला उदाहरण क्यों काम करता है इस पर प्रकाश डाला जा सकता है - ऐसा लगता है कि ओवरलोडेड जेनेरिक तरीकों के बताए गए हैंडलिंग के खिलाफ?
और जानकारी:
प्रति दाऊद के सुझाव, मूल उदाहरण के लिए, javac 1.6 से पालन किया, जावा 1.5 के तहत चलेगा:
$ javac -target 1.5 TestErasure.java
$ java -version
java version "1.5.0_19"
$ java TestErasure
method(List<Object> list)
method(List<String> list)
(मिट) वापसी प्रकार मीटर का हिस्सा है: 'का वर्णन फिर से जावा के सभी संस्करणों में ethod हस्ताक्षर। –
रिटर्न प्रकार विधि वर्णनकर्ता का हिस्सा है, लेकिन विधि हस्ताक्षर नहीं, सही है? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20a%20method%20 हस्ताक्षर? –
@ टॉम - मेरा मानना है कि आप गलत हैं - "परिभाषा: विधि घोषणा के दो घटकों में विधि हस्ताक्षर-विधि का नाम और पैरामीटर प्रकार शामिल हैं।" Http://java.sun.com/docs/books/tutorial/java/javaOO/methods.html से। विधि हस्ताक्षर काम करने के लिए विधि अधिभार के लिए अद्वितीय होना चाहिए, और वे वापसी प्रकार (जावा के लिए, कम से कम) पर भरोसा नहीं करते हैं। – weiji