2017-05-10 4 views
18
public class Program { 

    private static <Program> void foo(Program x){ 
     System.out.println(x+"-->1"); 
    } 

    private static void foo(final int i){ 
     System.out.println(i+"-->2"); 
    } 

    public static void main(String[] args) { 
     Integer i = 10; 
     foo(i); 
    } 

} 

और उत्पादन होता है:जावा में जेनेरिक निम्नलिखित प्रोग्राम के लिए कैसे काम करता है?

10-->1 

मैं इस विषय पर किसी भी प्रासंगिक चर्चा को खोजने के लिए सक्षम नहीं था। हालांकि, एक अलग विषय का जवाब मुझे एक छोटे से उलझन में: - Return Type of Java Generic Methods

उनके मुताबिक सामान्य <Program> अगर मैं इस कार्यक्रम के रूप में नीचे तो उत्पादन के लिए एक छोटे से बदल वापसी प्रकार के साथ लेकिन मेरे मामले में कोई संबंध नहीं है फरक है।

public class Program { 

    private static <Integer> void foo(Program x){ 
     System.out.println(x+"-->1"); 
    } 

    private static void foo(final int i){ 
     System.out.println(i+"-->2"); 
    } 

    public static void main(String[] args) { 
     Integer i = 10; 
     foo(i); 
    } 

} 

आउटपुट:

10-->2 

मैं JDK1.7

+0

आपके दूसरे उदाहरण में, केवल 'foo()' का दूसरा संस्करण एक हस्ताक्षर है जो आप 'मुख्य()' में जो कॉल कर रहे हैं उससे मेल खा सकता है। पहले उदाहरण में, एक प्राथमिकता नियम होना चाहिए जो अनबॉक्सिंग से पहले जेनेरिक फ़ंक्शन में 'इंटेगर' कॉल से मेल खाता है और विकल्प को कॉल करने पर विचार किया जाता है। –

+10

आप इस लाइन पर एक नया सामान्य प्रकार पैरामीटर 'प्रोग्राम' परिभाषित कर रहे हैं: 'निजी स्थिर शून्य foo (प्रोग्राम x) {'। उस प्रकार पैरामीटर के पास 'प्रोग्राम' नामक आपकी कक्षा के साथ कुछ लेना देना नहीं है।जब आप टाइप पैरामीटर का नाम 'इंटीजर' में बदलते हैं, तो पैरामीटर 'प्रोग्राम एक्स' अचानक आपके वास्तविक वर्ग 'प्रोग्राम' का एक प्रकार होता है। सबक: मौजूद वास्तविक वर्गों के लिए अपने प्रकार के पैरामीटर का नाम न दें। – marstran

+2

यदि आपका जेनेरिक पैरामीटर नाम एकल अपरकेस अक्षर के साथ वर्तनी के सम्मेलन का पालन करता है तो आपका कोड बहुत आसान होगा। भले ही, यह निराशाजनक रूप से भ्रमित हो रहा है जब आप उन्हें ठोस प्रकार के समान नाम देते हैं, जो कि कम से कम एक है। अपने जेनेरिक पैरामीटर नामों को अपने प्रकार के नाम से अलग करें! –

उत्तर

14

आपके पहले उदाहरण में, आप वास्तव में Program के तर्क को निर्दिष्ट नहीं कर रहे हैं, यह एक सामान्य है। उस प्रकार पैरामीटर के पास Program नामक आपकी कक्षा से कोई लेना देना नहीं है। आप इस प्रकार का टाइपो बनाकर एक ही परिणाम प्राप्त होगा:

public class Program { 

    private static <Programmmm> void foo(Programmmm x){ 
     System.out.println(x+"-->1"); 
    } 

    private static void foo(final int i){ 
     System.out.println(i+"-->2"); 
    } 

    public static void main(String[] args) { 
     Integer i = 10; 
     foo(i); 
    } 

} 

हालांकि, अपने दूसरे उदाहरण में, पैरामीटर सचमुच प्रकार Program की है और इसलिए यह जब foo(10); के रूप में बुलाया से मेल नहीं खाता है और आप दूसरे से परिणाम मिलता है तरीका।

13

पहले मामले में उपयोग कर रहा हूँ, Program सामान्य विधि के लिए इस्तेमाल किया पैरामीटर का नाम है। यह कोई नाम हो सकता है। महत्वपूर्ण बात यह है कि विधि तर्क एक ऑब्जेक्ट है, इसलिए जब आप अपनी विधि को इंटीजर तर्क के साथ कॉल करते हैं, तो यह उस ऑब्जेक्ट का उपयोग करता है जो ऑब्जेक्ट लेता है।

दूसरे मामले में सामान्य पैरामीटर का नाम Integer (ऐसा नहीं करें) लेकिन विधि लेने का तर्क एक कार्यक्रम है। तो इसे एक इंटीजर के साथ बुलाकर, Object या पूर्णांक संस्करण मान्य नहीं है, इसलिए यह मान को अनबॉक्स करता है।

method overloading के संदर्भ में, जो ओवरलोडिंग का समाधान किया गया है, का वर्णन करता है। यह आपको बताएगा कि पहला संस्करण int विधि के बजाय Object विधि का उपयोग क्यों करता है।

दूसरा मुद्दा यह है कि आपने अपने सामान्य पैरामीटर ठोस प्रकारों का नाम दिया है, जो भ्रमित है। यह देखना आसान है कि आप ऐसा नहीं करते हैं।

private static <T> void foo(T x){ 
    System.out.println(x+"-->1"); 
} 

अब यह स्पष्ट है, T एक पैरामीटरयुक्त तर्क है। अपने दूसरे संस्करण में,

private static <T> void foo(Program x){ 
    System.out.println(x+"-->1"); 
} 

अब यह स्पष्ट बस किसी भी वस्तु है, अपने तर्क है एक कार्यक्रम वस्तु है, और नहीं।

+0

बोनस पॉइंट यदि आपको जेएलएस के प्रासंगिक भाग की तरह लगता है तो इस^^ –

+0

पर टाइप करें पैरामीटर 'प्रोग्राम' को कॉल न करें, क्योंकि यह उसकी मुख्य कक्षा का नाम है। जब वह टाइप पैरामीटर को 'इंटीगर' में बदलता है, तो पैरामीटर प्रकार अचानक वास्तविक वर्ग 'प्रोग्राम' में बदल जाता है। – marstran

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