2011-06-12 12 views
8

मैं जावा फ़ंक्शन के प्रोटोटाइप को लिखने की कोशिश कर रहा हूं जिसे किसी भी पूर्णांक और तारों के साथ बुलाया जा सकता है:विधि प्रोटोटाइप में varargs के लिए एकाधिक ऑब्जेक्ट प्रकार?

myMethod(1, 2, 3, "Hello", "World"); // Valid call 
myMethod(4, "foo", "bar", "foobar"); // Valid call 

आदर्श रूप से, मैं किसी भी क्रम में इंक और तारों को देना चाहता हूं (और संभवतः मिश्रित):

myMethod(1, "Hello", 2, "World", 3); // Valid call 

मैंने varargs का उपयोग करने के बारे में सोचा, लेकिन प्रोटोटाइप में केवल एक ही हो सकता है। मेरे पास एक और विचार है जो निम्नलिखित प्रोटोटाइप का उपयोग करना है:

public void myMethod(Object ... objs) { [...] } 

... लेकिन मुझे लगता है कि अगर संकलित प्रकारों के अलावा किसी अन्य चीज़ के साथ कहा जाता है तो संकलन त्रुटि होनी चाहिए। बेशक, एक रनटाइम चेक (instanceof) किया जा सकता है, लेकिन यह एक बहुत ही सुरुचिपूर्ण समाधान नहीं होगा, है ना?

आप यह कैसे करेंगे?

उत्तर

5

जावा प्रोग्रामिंग भाषा में इसे काम करने के लिए कोई रास्ता नहीं है ताकि आप स्ट्रिंग्स और पूर्णांक की मनमानी संख्या पारित कर सकें, और जब आप स्ट्रिंग या पूर्णांक से कुछ और पास करते हैं तो संकलक त्रुटि देता है।

+0

यही वह था जिसे मैं डरता था। धन्यवाद, मैं तब ऑब्जेक्ट varargs का सहारा लेगा। – executifs

3

दो प्रकार के मैच के लिए जेनरिक का उपयोग करने का कोई तरीका नहीं है, जैसे नहीं है

public <T extends String | Integer> void myMethod(T... objs); // You can't do this 
+0

बहुत खराब :(यह एक अच्छा फीचर हालांकि – executifs

+3

नहीं वास्तव में यही सामान्य प्रकार के व्यर्थ होगा और कोड यादृच्छिक ClassCastExceptions होने का खतरा हो सकता है हो सकता है;।। – Jeshurun

+1

मुझे आश्चर्य है अगर किसी को भी आँख बंद करके कॉपी/इस कोड को चिपकाया गया है, यह काम करने के लिए उम्मीद कर रहा, और फिर निराश हो गया जब उसने ऐसा नहीं किया –

6

आप इसे प्रकार सुरक्षित, मैं इस के साथ जाना चाहते हैं होना चाहते हैं:

public myMethod(Thing<?>... thing) { ... } 

और फिर बनाने के अपने बात कक्षाएं:

public interface Thing<T> { 
    public T value(); 
} 

public class IntThing implements Thing<Integer> { 
    private final int value; 

    public IntThing(int value) { 
     this.value = value; 
    } 

    public Integer value() { 
     return value; 
    } 
} 

मैं इसे अपनी कल्पना के लिए छोड़ पता लगाने StringThing लिखने के लिए कैसे करने के लिए होगा। जाहिर है, "चीज" से बेहतर नाम का उपयोग करें, लेकिन मैं उसमें आपकी सहायता नहीं कर सकता।

public static Thing<Integer> thing(int value) { 
    return new IntThing(value); 
} 

public static Thing<String> thing(String value) { 
    return new StringThing(value); 
} 

तो फिर तुम thing के लिए एक कॉल में प्रत्येक वस्तु लपेट:

myMethod(thing(1), thing(2), thing(3), thing("Hello"), thing("World")); 

गन्दा

फिर आप दो स्थिर तरीकों बनाते हैं? हाँ। दुर्भाग्य से, जावा में इस सामान को अन्य भाषाओं की तरह छिपाने की क्षमता नहीं है। स्कैला के निहित defs आपको यहां मदद करेंगे, लेकिन यह अन्य समस्याओं की पूरी बैरल के साथ आता है। व्यक्तिगत रूप से, मैं instanceof चेक के साथ जाऊंगा, लेकिन यह सुनिश्चित करेगा कि आपका कोड संकलन-समय पर सुरक्षित है।

+0

धन्यवाद, यह काम करेगा, लेकिन 'Thing' आवरण शायद एपीआई उपयोगकर्ताओं को भ्रमित करेंगे। की अनुमति दे उन्हें भी कैसे यह काम करता है type- से मेरे लिए ज्यादा महत्वपूर्ण है के बारे में सोच के बिना' myMethod' कॉल करने के लिए सुरक्षा – executifs

+0

उस स्थिति में, आपके varargs विचार शायद सबसे अच्छा है। –

1

आपके द्वारा वर्णित समस्या का एकमात्र संभावित समाधान वह है जो पहले से ही कहा गया है, जहां फ़ंक्शन Object प्रकार के varargs तर्क में लेता है। यह जावा में प्रतिबंध के कारण है जहां विधि हस्ताक्षर में केवल एक vararg हो सकता है, और यह अंतिम पैरामीटर होना चाहिए।

यह कहना मुश्किल है कि आपके पास myMethod का इरादा रखने के विवरण के बिना वैकल्पिक वैकल्पिक समाधान क्या हो सकता है।

1

(वर्कअराउंड)

अपने lib में जोड़ें:

package mylib; 

public class Lang { 
    public static <T> T[] varargs (T...ts) { 
     return ts; 
    } 
} 

अपने कार्यक्रम में: (कई कोडिंग शैली नियमों को तोड़ने)

package myprog; 

import static mylib.Lang.*; 

public class MyProg { 

    public static void testfunc (Integer[] ints, String[] strs) { 

     for (int i : ints) 
      System.out.println(i); 

     for (String s : strs) 
      System.out.println(s); 
    } 

    public static void main (String[] args) { 
     testfunc(
      varargs(1,2,3), 
      varargs("Sophia", "Jacob") 
     ); 
    } 
} 

0

वाक्य रचना की अनुमति दी है

public class Foo<T extends Number & List> { 
    ... 
} 

प्रकार परिवर्तनीय TNumber और List के उप प्रकार के प्रकारों को टाइप करें (उदाहरण के लिए, एकाधिक इंटरफेस को लागू करने वाले प्रकार)।

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