2014-08-30 9 views
20

मैं उस प्रकार के एक सरणी में एक प्रकार का एक varargs को बदलने के लिए util विधि का एक प्रकार है - यह इस तरह दिखता है:क्या varargs का यह उपयोग सुरक्षित है?

public K[] array(K... ks) { 
    return ks; 
} 

उपयोग के मामले तो यह है कि बजाय जब एक विधि बुला एक सरणी को परिभाषित जिसके लिए एक सरणी की आवश्यकता होती है, आप केवल सरणी (val1, val2, val3) कर सकते हैं।

हालांकि, इंटेलिजे मुझे प्रदूषण चेतावनी ढेर देता है। मैं समझता हूं कि इसका मतलब क्या है, लेकिन मुझे विनिर्देशों के साथ अधिक अनुभव नहीं है - इसलिए, मैं जानना चाहता हूं कि मैं @ सेफ वर्गार्ग जोड़ सकता हूं और क्या यह विधि वास्तव में सुरक्षित है या नहीं।

इंटेलीजे का कहना है:

समस्या सार संभव ढेर लाइन पर पैरामिट्रीकृत vararg प्रकार से प्रदूषण 249

समस्या समाधान अंतिम करें और व्याख्या के रूप में @SafeVarargs

कश्मीर के रूप में घोषित किया जाता है वी।

+13

IMO आप इस तरह के विधि की जरूरत नहीं है, बस का उपयोग 'जो कुछ भी [] whateverArray = {VAL1, val2, val3, ...};' –

+0

आप ढेर प्रदूषण चेतावनी के * सटीक * जानकारी दे सकते हैं? और टाइप पैरामीटर 'के' घोषित कहां है? –

+0

@ लुइगी, हाँ, लेकिन यह एक उपयोगिता है। 'के [] कुंजी = {key1, key2, key3}; object.method (कुंजी); 'बनाम 'object.method (सरणी (key1, key2, key3));' - दूसरा लिखना बहुत आसान है, खासकर जब आप इसे बहुत कुछ कर रहे हैं। – DziNeIT

उत्तर

24

के साथ, कक्षा के पैरामीटर टाइप करें, नहीं, यह सुरक्षित नहीं है - अगर जेनेरिक का उपयोग कर रहे किसी अन्य विधि से कहा जाता है। यहां एक संपूर्ण उदाहरण जो ठीक लग रहा है, लेकिन एक अपवाद फेंकता है:

class Utility<K> { 
    public K[] array(K... ks) { 
     return ks; 
    } 

    public K[] otherMethod(K k1, K k2) { 
     return array(k1, k2); 
    } 
}  

class Test { 
    public static void main(String[] args) throws Exception { 
     Utility<String> util = new Utility<String>(); 
     // Bang! 
     String[] array = util.otherMethod("foo", "bar"); 
    } 
} 

जब संकलक otherMethod के लिए बाईटकोड बनाता है, जिसे array में पारित करने के लिए सही तरह की एक सरणी का निर्माण नहीं सकता है, क्योंकि यह K के प्रकार को नहीं जानता है। मिटाए जाने के कारण, यह मानों के साथ सिर्फ Object[] बनाता है। तो main में, otherMethod से String[] के परिणामस्वरूप एक छिपी हुई कलाकार है ... और यह निष्पादन समय पर विफल हो जाती है।

आप कोड जो वास्तव में तर्क के प्रकार जानता है से सीधे array फोन है, तो यह ठीक है, क्योंकि परोक्ष रूप से बनाए गए सरणी सही प्रकार का हो जाएगा।

+0

धन्यवाद। जब तक यह केवल (कारण के भीतर) स्थिति है जो किसी समस्या का कारण बन सकती है, जो मैं कर रहा हूं उसके लिए ठीक होना चाहिए। – DziNeIT

+3

यहां वास्तविक सावधानी बरतें, @DziNeIT। अगर यह सिर्फ एक मूर्खता है और आप इस कोड का उपयोग कर एकमात्र व्यक्ति हैं, तो आगे बढ़ें। मुझे पता है कि अगर मैं ऐसा कुछ करता हूं तो मेरी राय क्या होगी। हालांकि, यह एक अच्छा सवाल है, हालांकि यह एक अच्छा सवाल है। :) – TEK

0

आप बस अपनी विधि को उचित सरणी में परिवर्तित करने के बारे में बता सकते हैं। एक तरीका मैंने पाया कि सरणी को चर के साथ विधि में पास करना था, और उसके बाद प्रतिलिपि बनाना था।

public K[] otherMethod(K[] parent, K k1, K k2) { 
    List<K> list = new ArrayList<K>(); 
    Collections.addAll(list, array(k1, k2)); 
    list.toArray(parent); 
    return parent; 
} 

अब उत्पादन Collections.toArray() विधि है, जो अशक्त रिटर्न अगर वहाँ सरणी में पर्याप्त स्थान नहीं है, या वहाँ है अगर अतिरिक्त स्थान अप्रयुक्त मूल्यों अशक्त हो जाएगा पर निर्भर करता है।

class Test { 
    public static void main(String[] args) throws Exception { 
     Utility<String> util = new Utility<String>(); 
     String[] array = util.array("one", "two", "three"); 
     array = util.otherMethod(array, "x", "y"); 
     printArr(array); // prints: x y null 

     Utility<Integer> util2 = new Utility<Integer>(); 
     Integer[] intarray = util2.otherMethod(new Integer[1], 1, 2); 
     printArr(intarray); // prints: null 
     Integer[] intarray = util2.otherMethod(new Integer[2], 1, 2); 
     printArr(intarray); // prints: 1 2 
    } 

    static void printArr(Object[] objArr) { 
     for (Object o:objArr) System.out.print(o+"\t"); 
    } 
} 
संबंधित मुद्दे