2015-10-27 11 views
7

मैं "से जावा कोड के इस टुकड़े है - एक शुरुआत गाइड - Schildt ', अध्याय 13:।जेनेरिक विधि मंगलाचरण

package com.chapter.thirteen; 

public class GenericMethodDemo { 
static <T extends Comparable<T>, V extends T> boolean arraysEqual(T[] x, V[] y){ 
    if(x.length != y.length) return false; 

    for(int i = 0; i < x.length; i++) 
     if(!x[i].equals(y[i])) return false; 

    return true; 
} 

public static void main(String args[]){ 

    Integer [] nums = { 1, 3, 3, 4, 6 }; 
    Integer [] nums2 = { 1, 3, 3, 4, 6 }; 
    Integer [] nums3 = { 1, 3, 3, 4, 6 }; 
    Integer [] nums4 = { 1, 3, 3, 4, 6, 7}; 
    Double [] dVals = {1.1, 2.2, 3.3, 4.4}; 

    if(arraysEqual(nums, nums)) 
     System.out.println("nums equal nums"); 

    if(arraysEqual(nums, nums2)) 
     System.out.println("nums equal nums2"); 

    if(arraysEqual(nums, nums2)) 
     System.out.println("nums equal nums2"); 

    if(arraysEqual(nums, nums3)) 
     System.out.println("nums equal nums3"); 

    if(arraysEqual(nums, nums4)) 
     System.out.println("nums equal nums4"); 

    //Edit:Removed the comments from the below two lines. 

    if(arraysEqual(nums, dVals)) 
     System.out.println("Nums equal dVals"); 

    } 
} 

संकलन संदेश के साथ विफल रहता है - "Error:(39, 12) java: method arraysEqual in class com.chapter.thirteen.GenericMethodDemo cannot be applied to given types; required: T[],V[] found: java.lang.Integer[],java.lang.Double[] reason: inference variable T has incompatible bounds equality constraints: java.lang.Integer lower bounds: V,java.lang.Double,java.lang.Integer", जो उम्मीद है

हालांकि, जब मैं (के रूप में नीचे दिए गए कोड में दिखाया गया है) तुलनीय करने के लिए पैरामीटर जोड़ने, कोड संकलित करता है तथा सही परिणाम पैदा करता है।

package com.chapter.thirteen; 


public class GenericMethodDemo { 
    static <T extends Comparable, V extends T> boolean arraysEqual(T[] x, V[] y){ 
    if(x.length != y.length) return false; 

    for(int i = 0; i < x.length; i++) 
     if(!x[i].equals(y[i])) return false; 

    return true; 
} 

public static void main(String args[]){ 

    Integer [] nums = { 1, 3, 3, 4, 6 }; 
    Integer [] nums2 = { 1, 3, 3, 4, 6 }; 
    Integer [] nums3 = { 1, 3, 3, 4, 6 }; 
    Integer [] nums4 = { 1, 3, 3, 4, 6, 7}; 
    Double [] dVals = {1.1, 2.2, 3.3, 4.4}; 

    if(arraysEqual(nums, nums)) 
     System.out.println("nums equal nums"); 

    if(arraysEqual(nums, nums2)) 
     System.out.println("nums equal nums2"); 

    if(arraysEqual(nums, nums2)) 
     System.out.println("nums equal nums2"); 

    if(arraysEqual(nums, nums3)) 
     System.out.println("nums equal nums3"); 

    if(arraysEqual(nums, nums4)) 
     System.out.println("nums equal nums4"); 

    if(arraysEqual(nums, dVals)) 
     System.out.println("Nums equal dVals"); 
    } 
} 
याद किया

क्या कोई यह बता सकता है कि संकलन दूसरे उदाहरण में क्यों विफल नहीं होता है? मुझे उम्मीद थी कि संकलक टी की शिकायत करने के लिए तुलनात्मक रूप से विस्तारित है, वी दूसरे उदाहरण में टी बढ़ाता है?

क्या चल रहा है?

+0

आपका पहला कोड भी संकलित करता है। आप किस जावा संस्करण का उपयोग कर रहे हैं? – Ruben

+0

जब आप 'तुलनात्मक' से टाइप पैरामीटर को हटाते हैं, तो आप कच्चे प्रकार का उपयोग शुरू कर रहे हैं और कहानी पूरी तरह से अलग हो जाती है। कच्चे प्रकार केवल पूर्व-जावा -5 कोड के साथ संगतता के लिए मौजूद हैं और इन्हें नए संगतता में उपयोग नहीं किया जाना चाहिए, जिन्हें ऐसी संगतता की आवश्यकता नहीं है। कच्चे प्रकार के काम करते समय और कब नहीं, आपको समझने की कोशिश नहीं करनी चाहिए, आपको इसके बारे में भूल जाना चाहिए। –

+0

हाय, मैं इंटेलिजे आईडीईए 14.1.5 सामुदायिक संस्करण पर जावा संस्करण 1.8.0_65 का उपयोग कर रहा हूं। धन्यवाद – theguyoverthere

उत्तर

0

विधि arraysEqual को V टाइप करने के लिए घोषित किया गया है जिसमें T सुपरर्ट टाइप के रूप में है। दूसरे शब्दों में V को T लागू या विस्तार करना होगा। यह java.lang.Double (V) और java.lang.Integer (T) के साथ मामला नहीं है, और इसलिए संकलन त्रुटि का गठन होता है।

संपादित जोड़ने के लिए Comparable से parameterization निकालते हैं (यह घोषणा Comparable नहीं Comparable<T> के रूप में) संकलक TComparable के रूप में, नहीं के रूप में Comparable<Integer>, और फिर VV extends Comparable जो java.lang.Double है के रूप में देखा जाता है देखता है।

+0

सवाल यह नहीं है कि पहला कोड त्रुटि उत्पन्न करता है, लेकिन दूसरा कोड संकलित क्यों करता है। स्पष्टीकरण के लिए –

2

कारण PECS के नियमों के कारण है।

जब आप ऐसा करेंगे,

static <T extends Comparable, V extends T> boolean arraysEqual(T[] x, V[] y) 

आप मूल रूप से यह स्पष्ट करते हैं, दोनों टी और वी Comparable के उप प्रकार हैं। जिसका अर्थ है arraysEqual(Integer[], Double[]) को कॉल करना चाहिए क्योंकि Integer और DoubleComparable लागू करें।

लेकिन जब आप Comparable के लिए सामान्य प्रकार जोड़ने के लिए, अनुबंध खो दिया है,

static <T extends Comparable<T>, V extends T> boolean arraysEqual(T[] x, V[] y) 

इस में, DoubleComparable<Integer> को लागू नहीं है, यही वजह है कि संकलक त्रुटि है।

संपादित करें: अपने प्रश्न है क्यों rawtype Comparable संकलक त्रुटि है नहीं है, तो जवाब है कि कैसे जेनरिक काम है ...

आप Number भी साथ की कोशिश कर सकते

static <T extends Number, V extends T> boolean arraysEqual(T[] x, V[] y) 

कच्चे प्रकार इसमें शामिल हैं, और आप arrayEquals(Integer[], Double[]) पर कॉल कर सकते हैं और यह ठीक काम करेगा क्योंकि Number दोनों हैं।

+0

धन्यवाद। मैंने अभी तक "कच्चे प्रकार" पर पढ़ा नहीं है। "कच्चे प्रकार और विरासत संहिता" पर अनुभाग अध्याय में अगला आता है। मैंने फ़ंक्शन आमंत्रण को गलत तरीके से टाइप किया था और संकलन विफल होने की उम्मीद थी। जब यह नहीं हुआ तो यह मुझे परेशान कर दिया! आपके उत्तर के लिए फिर से धन्यवाद। – theguyoverthere

0

आप जावा 7 javac के साथ संकलित करने के लिए प्रयास करते हैं तो तथ्य यह है कि यह एक कच्चे Comparable साथ सफल होता है जावा 8.

में सुधार प्रकार निष्कर्ष की वजह से वास्तव में है, आपको मिलता है:

 
      if(arraysEqual(nums, dVals)) 
      ^
    required: T[],V[] 
    found: Integer[],Double[] 
    reason: inferred type does not conform to declared bound(s) 
    inferred: Double 
    bound(s): Integer 
    where T,V are type-variables: 
    T extends Comparable declared in method arraysEqual(T[],V[]) 
    V extends T declared in method arraysEqual(T[],V[]) 

हालांकि, जावा 8 उन प्रकारों का एक उचित सेट खोजने की कोशिश कर रहा है जो सफलतापूर्वक बाधाओं को पूरा करते हैं। यह कहा गया कि सरणियों प्रकार Integer[] और Double[] हैं करने के बजाय, यह उन्हें Comparable[] और Double[] के रूप में लाने का प्रयास। DoubleComparable<Double> जिसका अर्थ है कि यह लागू करता है कच्चे Comparable को लागू करने की घोषणा की है।

यह जब सामान्य प्रकार ठीक से प्रयोग किया जाता है काम नहीं कर सकता, Integer रूप Comparable<Integer>, नहीं कच्चे Comparable को लागू करना तथा Double कि लागू नहीं करता है।

किताब में यह उदाहरण, एक सा काल्पनिक होने के लिए के रूप में आप वास्तव में विधि में compareTo का उपयोग नहीं कर रहे हैं। Double रूप

static <T, V extends T> boolean arraysEqual(T[] x, V[] y){...} 

यह Integer[] और Double[] के लिए जावा 7 में संकलित किया है नहीं होगा, Integer विस्तार नहीं करता है: यदि आप पूरी तरह से T पर बाधा हटा दिया था इसी अंक में चलाने होता है। लेकिन जावा 8 में यह संकलित है, क्योंकि इसके लिए T और Double फैली उस प्रकार Number & Comparable<?> infers। Number & Comparable<?>, सबसे सख्त आम प्रकार खोजने के लिए इतना है कि आप स्पष्ट डाली बिना प्रकार Number या Comparable<?> के एक चर करने के लिए टी आवंटित करने के लिए सक्षम हो जाएगा कोशिश कर जावा 8 का परिणाम है।

+0

एक छोटा सुधार, जब आप टी पर बाधा को हटाते हैं, तो इसे डिफ़ॉल्ट रूप से 'ऑब्जेक्ट' के रूप में अनुमानित नहीं किया जाएगा 'संख्या'। – Codebender

+0

@ कोडबेंडर वास्तव में, यह 'संख्या और तुलनात्मक ' प्रकार के रूप में, 'ऑब्जेक्ट' नहीं है। – RealSkeptic

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