java - संग्रह.मैक्स()हस्ताक्षर में ऑब्जेक्ट द्वारा बाध्य क्यों है?




generics (2)

बस जावा 7 के java.util.Collections वर्ग के कार्यान्वयन के माध्यम से चला गया, और कुछ ऐसा देखा जो मुझे समझ में नहीं आता है। max कार्य हस्ताक्षर में, T Object द्वारा बाध्य क्यों है?

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
    Iterator<? extends T> i = coll.iterator();
    T candidate = i.next();

    while (i.hasNext()) {
        T next = i.next();
        if (next.compareTo(candidate) > 0)
            candidate = next;
    }
    return candidate;
} 

ऑब्जेक्ट बाध्य छोड़ा गया है तो max ठीक काम करता प्रतीत होता है।

public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll) {
    Iterator<? extends T> i = coll.iterator();
    T candidate = i.next();

    while (i.hasNext()) {
        T next = i.next();
        if (next.compareTo(candidate) > 0)
            candidate = next;
    }
    return candidate;
}

क्या वास्तव में ऐसी कोई परिस्थितियां हैं जहां बाध्यता एक अंतर बनाती है? यदि हां, तो कृपया एक ठोस उदाहरण प्रदान करें।


Answers

दोनों की एक ही सीमा है लेकिन एक सूक्ष्म अंतर है।

 <T extends Object & Comparable<? super T>> 

यह T को मिटाने के तहत एक Object बनने का कारण बन जाएगा।

 <T extends Comparable<? super T>>

यह T को मिटाने के तहत Comparable बनने का कारण बन जाएगा।

इस मामले में ऐसा इसलिए किया जाता है क्योंकि .max जावा 5 की भविष्यवाणी करता है। हम इस लिंक में देख सकते हैं जोआचिम ने कृपया प्रदान किया है कि जावा 1.4.2 में .max का हस्ताक्षर है:

public static Object max(Collection coll)

क्या हमने <T extends Comparable<? super T>> किया था <T extends Comparable<? super T>> <T extends Comparable<? super T>> एक बाध्य के रूप में, हमारे हस्ताक्षर होगा

public static Comparable max(Collection coll)

जो एपीआई तोड़ देगा। मैंने इस पृष्ठ को खोजने में कामयाब रहा है जो पुरानी एपीआई को जेनेरिक में परिवर्तित करने पर चर्चा करता है और यह एक विशिष्ट उदाहरण के रूप में .max देता है।

यहां वे बताते हैं कि इस तरीके को max क्यों परिभाषित किया गया है:

आपको यह भी सुनिश्चित करने की आवश्यकता है कि संशोधित एपीआई पुराने ग्राहकों के साथ बाइनरी संगतता बरकरार रखे। इसका तात्पर्य है कि एपीआई का क्षरण मूल, असंगत एपीआई जैसा ही होना चाहिए। ज्यादातर मामलों में, यह स्वाभाविक रूप से गिरता है, लेकिन कुछ सूक्ष्म मामले हैं। हम सामना किए गए सबसे सूक्ष्म मामलों में से एक की जांच करेंगे, विधि Collections.max() । जैसा कि हमने वाइल्डकार्ड के साथ सेक्शन मोर फन में देखा है, max() लिए एक व्यावहारिक हस्ताक्षर है:

public static <T extends Comparable<? super T>> T max(Collection<T> coll) public static <T extends Comparable<? super T>> T max(Collection<T> coll) यह ठीक है, सिवाय इसके कि इस हस्ताक्षर का क्षरण है: public static Comparable max(Collection coll) जो अधिकतम () के मूल हस्ताक्षर से अलग है: public static Object max(Collection coll)

कोई निश्चित रूप से अधिकतम () के लिए इस हस्ताक्षर को निर्दिष्ट कर सकता है, लेकिन यह नहीं किया गया था, और संग्रह की सभी पुरानी बाइनरी क्लास फ़ाइलें जो संग्रह.मैक्स () को कॉल करती हैं, ऑब्जेक्ट लौटने वाले हस्ताक्षर पर निर्भर करती हैं।


प्रतिबिंब नई वस्तुओं के तात्कालिकता, तरीकों का आविष्कार, और इसके कार्यान्वयन के पूर्व ज्ञान के बिना रन समय पर गतिशील रूप से कक्षा चर पर संचालन / सेट संचालन की अनुमति देता है।

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

उपर्युक्त उदाहरण में शून्य पैरामीटर वह ऑब्जेक्ट है जिसे आप विधि को आमंत्रित करना चाहते हैं। यदि विधि स्थिर है तो आप शून्य की आपूर्ति करते हैं। यदि विधि स्थैतिक नहीं है, तो आपको आमंत्रित करते समय आपको शून्य के बजाय एक मान्य MyObject उदाहरण प्रदान करने की आवश्यकता है।

प्रतिबिंब आपको कक्षा के निजी सदस्य / विधियों तक पहुंचने की अनुमति देता है:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • कक्षाओं के निरीक्षण के लिए (आत्मनिरीक्षण के रूप में भी जाना जाता है) आपको प्रतिबिंब पैकेज ( java.lang.reflect ) आयात करने की आवश्यकता नहीं है। क्लास मेटाडाटा को java.lang.Class माध्यम से एक्सेस किया जा सकता है।

प्रतिबिंब एक बहुत ही शक्तिशाली एपीआई है लेकिन यदि अतिरिक्त रूप से उपयोग किया जाता है तो यह एप्लिकेशन को धीमा कर सकता है, क्योंकि यह रनटाइम पर सभी प्रकारों को हल करता है।





java generics