2014-05-23 2 views
7

पूरा विचार है करने के लिए पूरे प्रश्न के माध्यम से जाने के लिए कृपया।मैं सामान्य वर्ग पर एक आंतरिक वर्ग की स्थिर विधि का सांख्यिकीय रूप से संदर्भ क्यों नहीं दे सकता?

सबसे पहले इस प्रकार जाने वर्ग Box दी गई है: -

public class Box <T>{ 
    private T t; 

    public void set(T t){ 
     this.t = t; 
     System.out.println("value:\n"); 
     System.out.printf("%s", t.toString()); 
    } 
    public T get() { 
     return t; 
    } 
    static int retInt(){ 
     return 5; 

    } 
    public <U extends Number> void inspect(U u){ 
      System.out.println("T: " + t.getClass().getName()); 
      System.out.println("U: " + u.getClass().getName()); 
     } 

} 

जेनेरिक वर्ग Util नीचे दिए गए: -

public class Util<T>{ 
    private T t; 

    //Generic method 
    public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) { 
     return p1.getKey().equals(p2.getKey()) && 
       p1.getValue().equals(p2.getValue()); 
    } 

    /* Static generic or non-generic methods can be declared in generic class 
     but they can not make use of generic parameter type(as generics static  
     methods using class type variable must know the type argument 
     (i.e value of type parameter); and knowledge of type argument is 
     possible only when object of same generic class are instantiated 
     (meaning assigning value of generic type parameter <T> or better to 
     say declared object have it's type argument; for example 
     as in List<T> replace T with Integer,String, Float etc); 
     but static method may be called without having 
     instance of class; so such declaration for static generic method are 
     not allowed) here it is <T>; like for example as shown below 

     public static int checkFun(T t){ 
      return 5; 
     } // this generate compiler error complaining "can not make static 
     // reference to non-static type T".   
    */ 


    public static <K> boolean cmp(Box<K> b1, Box<K> b2){ 
     // implement comparator to compare but here 
     return true; 
    } 

    // Inner class Pair 
    public class Pair <K, V> { 
     private K key; 
     private V value; 

     // Generic constructor 
     public Pair(K key, V value) { 
      this.key = key; 
      this.value = value; 
     } 

     public void setKey(K key) { 
      int i = 6; 
      if(i >4 || i<9); 
      this.key = key; 
     } 

     public void setValue(V value) { 
      this.value = value; 
     } 

     public K getKey(){ 
      return key; 
     } 

     public V getValue(){ 
      return value; 
     } 

    } 

    public void main1() {   
     //The complete syntax for invoking this method would be: 
     // <Integer, String> new Util<T>(). 
     Pair<Integer, String> p1 = new Pair<Integer,String>(1, "apple"); 
     Pair<Integer, String> p2 = new Pair<Integer, String>(2, "pear"); 
     boolean same = compare(p1, p2); 
     //boolean same = true; 
     if(same)System.out.println("it is true: they are the same"); 
     else System.out.println("nah! they are not the same..."); 

     //boolean sm = compare(); 
    } 

    public static void main (String[] args) /*throws FileNotFoundException */{ 
     //new Util<Integer>(). main1(); 

     Util<Integer> util = new Util<>(); 
     util.main1(); 
    } 
} 

कोड से ऊपर संकलित करता है तथा ठीक कार्यान्वित करता है, मेरी बेचैनी यहाँ निहित है:

यदि हम विधि

पर संशोधक जोड़ें
public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) -------(1) 
// called in method main1() 

और यह

public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2)  -------(2) 

तो संकलक शिकायत है कि गैर स्थिर प्रकार जोड़ी जबकि समान विधि

public static <K> boolean cmp(Box<K> b1, Box<K> b2) -------(3) 

करने के लिए एक स्थिर संदर्भ जो भी स्थिर है नहीं कर सकते, लेकिन नहीं करता है शिकायत नहीं यहां तक ​​कि हम दोनों विधि but विधि में एक big but हम eq-1 से बात कर रहे हैं तर्क इसे इस्तेमाल करता है भीतरी वर्ग Pair (तो मेरे अस्पष्टता के तर्क इस सुविधा के संदर्भ में समझा जा सकता है) से है में प्रकार पैरामीटर <T> उपयोग नहीं कर रहे, हालांकि।

लेकिन फिर भी; तार्किक रूप से, मुझे लगता है कि eq-1 में विधि के लिए संशोधक static जोड़ने टाइम त्रुटि संकलन निर्मित न करे क्योंकि जहाँ भी eq-2 में विधि कहा जाता है यह eq-2 में विधि करने के लिए सही तर्क के साथ कॉल करने के लिए है कि विधि की जिम्मेदारी होगी और यह कहा जा अनुमति दी जानी चाहिए एक स्थिर विधि की तरह।

प्रश्न: - क्या विधि के लिए स्थिर संशोधक का उपयोग करके नहीं के लिए विवरण है:

public <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) 

मदद के लिए धन्यवाद।

उत्तर

9

इस का कारण यह util वर्ग और भीतरी वर्ग जोड़ी गैर स्थिर है पर प्रकार पैरामीटर है। क्योंकि जोड़ी एक गैर स्थैतिक आंतरिक कक्षा है, यह यूटिल के टी प्रकार पैरामीटर का उपयोग कर सकती है (भले ही इस मामले में यह नहीं है)। इसलिए जब जोड़ी प्रयोग किया जाता है यह या तो एक util उदाहरण (जहां टी परोक्ष उपलब्ध है) के संदर्भ में तक पहुंच बनाकर या एक विशिष्ट Util<T>, उदा के माध्यम से एक्सेस करके उसका योग्यता से, एक टी निर्दिष्ट करने के लिए आवश्यक है Util<Integer>.Pair<String,Object>। एक और तरीका है इसके बारे में लगता है कि जोड़ी के प्रकार util के प्रकार के पैरामीटर पर निर्भर करता है और Util<String>.Pair<K,V>Util<Object>.Pair<K,V> के साथ संगत नहीं है।

util पर प्रकार पैरामीटर टी रखने के लिए और जोड़ी एक गैर स्थिर भीतरी वर्ग के रूप में रखने के लिए, आप

public static <T, K, V> boolean compare(Util<T>.Pair<K, V> p1, Util<T>.Pair<K, V> p2) 

या

public static <K,V> boolean compare(Util<?>.Pair<K,V> p1, Util<?>.Pair<K,V> p2) 

जो क्योंकि संभव है की तुलना के हस्ताक्षर को बदल सकते हैं टी का त्वरण विधि के शरीर के लिए प्रासंगिक नहीं है।

एक विकल्प के रूप में, के बाद से जोड़ी

public static class Pair <K, V> { /* ... */ } 
अंत में पूर्णता के लिए

होने के लिए, अगर util एक प्रकार नहीं था कुछ भी (गैर स्थिर) util आप जोड़ी की परिभाषा को बदल सकते हैं के अंदर का उल्लेख नहीं करता पैरामीटर तो

public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) 

और

public class Pair<K, V> { /* ... */ } 

ठीक हो जाएगा।

+0

, धन्यवाद आदमी। जैसा कि मेरा मानना ​​है कि आपने लगभग सभी भाग को कवर किया था। मेरे पास समस्या का एक प्रकार का समाधान था, लेकिन टाइप पैरामीटर टी रखने के लिए आपको दी गई पहली स्पष्टीकरण ने मेरे संदेह को आंशिक रूप से हटा दिया है। लेकिन फिर भी मैं स्थिर संशोधक का उपयोग न करने के लिए शिकायतकर्ता के आसपास अपना सिर प्राप्त करने में सक्षम नहीं हूं। आपने उद्धरण दिया ** इसलिए जोड़ी किसी संदर्भ में उपयोग की जानी चाहिए जहां एक विशेष टी उपलब्ध है ** unquote। जैसा कि मैंने अपने प्रश्न में कहा था (और मुझे विश्वास है, जहां मैं गलत हो सकता हूं) ** ** ** ** ** ** ** (यहां विधि ** main1() ** की वस्तु बनाने के दौरान जानकारी उपलब्ध होगी ** गैर स्थैतिक)। – zeal

+0

जैसा कि मैंने कॉलिंग विधि से ऊपर कहा है ** main1() ** को पैरामीटर टाइप करने के लिए तर्क (मान) की आवश्यकता है ताकि कक्षा का उद्देश्य ** जोड़ी ** स्वचालित रूप से ** टी ** का मान होगा, वर्ग जोड़ी का कौन सा उद्देश्य उपयोग कर सकता है (भले ही वे उपयोग नहीं कर रहे हैं)। तो, कृपया इस मुद्दे पर कुछ प्रकाश डालें ताकि मेरा भ्रम हटा दिया जा सके। – zeal

+0

@zeal आप सही हैं कि थोड़ा अस्पष्ट है, मैंने जवाब की उस वाक्य को बदल दिया। उम्मीद है कि अब यह और अधिक समझ में आता है। मैंने जेनेरिक वाइल्डकार्ड के बारे में कुछ नोट्स भी जोड़े जो पहले गायब थे। –

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