2010-09-17 15 views
38

मैं सिर्फ गुवा के ImmutableList पर देख रहा था और मैंने देखा कि of() विधि 12 बार ओवरलोड हो गई थी।अमरूद की अपरिवर्तनीय सूची में इतने सारे अधिभार क्यों हैं() विधियों?

यह मेरे लिए लग रहा है कि सब वे जरूरी था:

static <E> ImmutableList<E> of(); 
static <E> ImmutableList<E> of(E element); // not even necessary 
static <E> ImmutableList<E> of(E... elements); 

क्या इतने सारे समान विविधताओं होने के लिए कारण है?

+5

और वे सभी अपने पैरामीटर को एक आंतरिक varargs विधि में वैसे भी पास करते हैं ... हुह। मुझे इस पर एक भौहें उठाना होगा। हम्म, स्रोत की एक टिप्पणी है "ये ग्यारह तक चले जाते हैं। इसके बाद, आपको बस varargs फॉर्म मिलता है, और इसके साथ जो भी चेतावनियां आ सकती हैं। :(" मुझे यकीन नहीं है कि यह किस चेतावनी का जिक्र कर रहा है। –

+0

@ टिम, यह शायद कम से कम और ऊपर की ओर एक अच्छा जवाब देगा, और शायद स्वीकार्य उत्तर। – jjnguy

+7

ग्यारह तक जाने के लिए Google के लिए +1! – romacafe

उत्तर

39

वरर्ग और जेनेरिक अच्छी तरह से एक साथ नहीं खेलते हैं। Varargs विधियों जेनेरिक तर्क के साथ एक चेतावनी का कारण बन सकता है, और अधिभार उस दुर्लभ मामले को छोड़कर उस चेतावनी को रोकता है जिसे आप of() का उपयोग कर अपरिवर्तनीय सूची में 11 से अधिक आइटम जोड़ना चाहते हैं।

स्रोत में टिप्पणी कहते हैं:

इन ग्यारह तक जा। उसके बाद, आपको बस varargs फॉर्म मिलता है, और इसके साथ जो भी चेतावनियां आ सकती हैं। :(कि

नोट जावा 7 के @SafeVarargs एनोटेशन विशेष रूप से जोड़ा गया था बात की इस तरह की आवश्यकता को समाप्त करने के लिए। एक एकल of(E...) विधि @SafeVarargs साथ एनोटेट इस्तेमाल किया जा सकता और सामान्य तर्क के साथ चेतावनी देना नहीं होता।

+0

अरे, क्या आप संभावित रूप से @Rinke द्वारा संदर्भित प्रदर्शन भाग को प्रतिबिंबित करने के लिए अपना उत्तर अपडेट कर सकते हैं? मुझे लगता है कि यह उल्लेख करने लायक है। –

+2

@ JoãoRebelo: हालांकि यह वास्तव में सच नहीं है ... विधियां तुरंत तुरंत जाती हैं और एक varargs विधि स्वयं को कॉल करें। – ColinD

+0

क्या आपका मतलब इस विशिष्ट मामले में है? या मैं गलत समझ रहा हूं कि आपका क्या मतलब था? –

13

एक प्रदर्शन कारण भी है। एक varargs विधि के प्रत्येक आमंत्रण एक सरणी आवंटन और प्रारंभिक कारण बनता है। यदि आपने किसी भी तरह से निर्धारित किया है कि उदाहरण के लिए 95% कॉल 3 या उससे कम तर्क के साथ हैं और 4 या उससे अधिक के साथ केवल 5% हैं, तो इस तरह अधिभार

public static <E> ImmutableList<E> of(); 
public static <E> ImmutableList<E> of(E e); 
public static <E> ImmutableList<E> of(E e1, E e2); 
public static <E> ImmutableList<E> of(E e1, E e2, E e3); 
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E... es); 

मामलों में से 95% मामलों में एक अच्छा प्रदर्शन बढ़ावा देता है। अलग-अलग डालें, औसत केस प्रदर्शन बढ़ जाता है।

+6

नोट: हालांकि सिद्धांत धारण करता है, मैंने अभी कॉलिन से सीखा है कि यह वास्तव में गुवा के लिए सच नहीं है क्योंकि ओवरलोडेड विधियों के परिणामस्वरूप वैसे भी एक वर्गास कॉल होता है (वर्तमान कार्यान्वयन में)। – Rinke

4

अन्य महान उत्तरों के अलावा, एक सूक्ष्म रनटाइम प्रदर्शन लाभ (सरणी आवंटन से बचने के अलावा) है, जो कि शून्य-तर्क और एकल-बहस ओवरलोड्स को कार्यान्वयन लौटाता है जो खाली प्रतिनिधित्व के लिए अनुकूलित किए जाते हैं और एकल-घटना सूची (क्रमशः)।

हम इन के लिए अलग विधि भार के पास नहीं था और केवल शामिल एक भी varargs आधारित पद्धति, तो उस विधि कुछ इस तरह दिखेगा:

public static <E> ImmutableList<E> of(E... es) { 
    switch (es.length) { 
     case 0: 
     return emptyImmutableList(); 
     case 1: 
     return singletonImmutableList(es[0]); 
     default: 
     return defaultImmutableList(es); 
    } 
} 

स्विच मामले के प्रदर्शन (या यदि - चेक चेक) अधिकांश कॉल के लिए बुरा नहीं होगा, लेकिन यह अभी भी अनावश्यक है क्योंकि प्रत्येक ऑप्टिमाइज़ेशन के लिए विधि ओवरलोड हो सकता है, और कंपाइलर हमेशा जानता है कि किस ओवरलोड को कॉल करना है। क्लाइंट कोड पर कोई बोझ नहीं है, इसलिए यह एक आसान जीत है।

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

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