जवाबों:
मुद्दा यह है कि जब आप शाब्दिक अशक्त का उपयोग करते हैं, तो जावा को नहीं पता होता है कि यह किस प्रकार का होना चाहिए। यह एक अशक्त वस्तु हो सकती है, या यह एक अशक्त वस्तु सरणी हो सकती है। किसी एक तर्क के लिए यह बाद की बात मानता है।
आपके पास दो विकल्प हैं। स्पष्ट रूप से टाइप किए गए वैरिएबल का उपयोग करके विधि को कॉल या कॉल करने के लिए अशक्त रूप से कास्ट करें। नीचे दिए गए उदाहरण देखें:
public class Temp{
public static void main(String[] args){
foo("a", "b", "c");
foo(null, null);
foo((Object)null);
Object bar = null;
foo(bar);
}
private static void foo(Object...args) {
System.out.println("foo called, args: " + asList(args));
}
}
आउटपुट:
foo called, args: [a, b, c]
foo called, args: [null, null]
foo called, args: [null]
foo called, args: [null]
asList()
से एक स्थिर आयात है java.util.Arrays
। मैंने सिर्फ यह माना कि यह स्पष्ट था। हालाँकि अब जब मैं इसके बारे में सोच रहा हूँ, तो मुझे शायद इसका उपयोग करना चाहिए था Arrays.toString()
क्योंकि इसका एकमात्र कारण यह सूची में परिवर्तित हो जाता है, इसलिए यह सुंदर रूप से छपेगा।
आपको एक स्पष्ट कलाकार चाहिए Object
:
foo((Object) null);
अन्यथा तर्क को संपूर्ण सरणी माना जाता है जो कि वैरग का प्रतिनिधित्व करता है।
यह बताने के लिए एक टेस्ट केस:
एक vargg- लेने की विधि घोषणा के साथ जावा कोड (जो स्थिर होने के लिए होता है):
public class JavaReceiver {
public static String receive(String... x) {
String res = ((x == null) ? "null" : ("an array of size " + x.length));
return "received 'x' is " + res;
}
}
यह जावा कोड (एक JUnit4 परीक्षण मामला) ऊपर कहता है (हम परीक्षण मामले का उपयोग कुछ भी परीक्षण करने के लिए नहीं कर रहे हैं, बस कुछ उत्पादन उत्पन्न करने के लिए):
import org.junit.Test;
public class JavaSender {
@Test
public void sendNothing() {
System.out.println("sendNothing(): " + JavaReceiver.receive());
}
@Test
public void sendNullWithNoCast() {
System.out.println("sendNullWithNoCast(): " + JavaReceiver.receive(null));
}
@Test
public void sendNullWithCastToString() {
System.out.println("sendNullWithCastToString(): " + JavaReceiver.receive((String)null));
}
@Test
public void sendNullWithCastToArray() {
System.out.println("sendNullWithCastToArray(): " + JavaReceiver.receive((String[])null));
}
@Test
public void sendOneValue() {
System.out.println("sendOneValue(): " + JavaReceiver.receive("a"));
}
@Test
public void sendThreeValues() {
System.out.println("sendThreeValues(): " + JavaReceiver.receive("a", "b", "c"));
}
@Test
public void sendArray() {
System.out.println("sendArray(): " + JavaReceiver.receive(new String[]{"a", "b", "c"}));
}
}
JUnit परीक्षण की उपज के रूप में इसे चलाना:
sendNothing (): प्राप्त 'x' आकार 0 की एक सरणी है sendNullWithNoCast (): प्राप्त 'x' शून्य है sendNullWithCastToString (): प्राप्त 'x' आकार 1 की एक सरणी है sendNullWithCastToArray (): प्राप्त 'x' शून्य है sendOneValue (): प्राप्त 'x' आकार 1 की एक सरणी है sendThreeValues (): प्राप्त 'x' आकार 3 की एक सरणी है sendArray (): प्राप्त 'x' आकार 3 की एक सरणी है
इसे और अधिक दिलचस्प बनाने के लिए, हम receive()
ग्रूवी 2.1.2 से फ़ंक्शन को कॉल करें और देखें कि क्या होता है। यह पता चला है कि परिणाम समान नहीं हैं! हालांकि यह एक बग हो सकता है।
import org.junit.Test
class GroovySender {
@Test
void sendNothing() {
System.out << "sendNothing(): " << JavaReceiver.receive() << "\n"
}
@Test
void sendNullWithNoCast() {
System.out << "sendNullWithNoCast(): " << JavaReceiver.receive(null) << "\n"
}
@Test
void sendNullWithCastToString() {
System.out << "sendNullWithCastToString(): " << JavaReceiver.receive((String)null) << "\n"
}
@Test
void sendNullWithCastToArray() {
System.out << "sendNullWithCastToArray(): " << JavaReceiver.receive((String[])null) << "\n"
}
@Test
void sendOneValue() {
System.out << "sendOneValue(): " + JavaReceiver.receive("a") << "\n"
}
@Test
void sendThreeValues() {
System.out << "sendThreeValues(): " + JavaReceiver.receive("a", "b", "c") << "\n"
}
@Test
void sendArray() {
System.out << "sendArray(): " + JavaReceiver.receive( ["a", "b", "c"] as String[] ) << "\n"
}
}
यह एक JUnit परीक्षण के रूप में चलाने से जावा में बोल्ड में अंतर के साथ, निम्नलिखित पैदावार होती है।
sendNothing (): प्राप्त 'x' आकार 0 की एक सरणी है sendNullWithNoCast (): प्राप्त 'x' शून्य है sendNullWithCastToString (): प्राप्त 'x' शून्य है sendNullWithCastToArray (): प्राप्त 'x' शून्य है sendOneValue (): प्राप्त 'x' आकार 1 की एक सरणी है sendThreeValues (): प्राप्त 'x' आकार 3 की एक सरणी है sendArray (): प्राप्त 'x' आकार 3 की एक सरणी है
मैं पसंद करता हूं
foo(new Object[0]);
अशक्त सूचक अपवादों से बचने के लिए।
आशा करता हूँ की ये काम करेगा।
foo()
?
ऑर्डर ओवरलोडिंग रिज़ॉल्यूशन के लिए ऑर्डरिंग ( https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.2 ) है:
पहले चरण में बॉक्सिंग या अनबॉक्सिंग रूपांतरण की अनुमति के बिना, या परिवर्तनशील एरिटी विधि मंगलाचरण का उपयोग किए बिना ओवरलोड रिज़ॉल्यूशन किया जाता है। यदि इस चरण के दौरान कोई लागू विधि नहीं मिलती है तो प्रसंस्करण दूसरे चरण में जारी रहता है।
यह गारंटी देता है कि जावा एसई 5.0 से पहले जावा प्रोग्रामिंग भाषा में मान्य किसी भी कॉल को अस्पष्टता के तरीकों, निहित बॉक्सिंग और / या अनबॉक्सिंग के परिणाम के रूप में अस्पष्ट नहीं माना जाता है। हालांकि, एक वेरिएबल एरिटी मेथड (.48.4.1) की घोषणा किसी दिए गए मेथड इनविटेशन एक्सप्रेशन के लिए चुने गए तरीके को बदल सकती है, क्योंकि पहले चरण में एक वेरिएबल एरिटी मेथड को एक निश्चित एरिटी मेथड के रूप में माना जाता है। उदाहरण के लिए, एक वर्ग में एम (ऑब्जेक्ट ...) घोषित करना जो पहले से ही एम (ऑब्जेक्ट) घोषित करता है, एम (ऑब्जेक्ट) का कारण अब कुछ इनवोकेशन एक्सप्रेशन (जैसे m (null)) के लिए नहीं चुना जाएगा, जैसा कि m (ऑब्जेक्ट [] ) अधिक विशिष्ट है।
दूसरा चरण बॉक्सिंग और अनबॉक्सिंग की अनुमति देते समय अधिभार संकल्प करता है, लेकिन फिर भी चर एरिटी विधि आह्वान के उपयोग को रोकता है। यदि इस चरण के दौरान कोई लागू विधि नहीं मिली है तो प्रसंस्करण तीसरे चरण में जारी है।
यह सुनिश्चित करता है कि वैरिएबल एरिटी मेथड इनवोकेशन के माध्यम से एक विधि को कभी नहीं चुना जाता है यदि यह निश्चित एरिटी मेथड इनवोकेशन के माध्यम से लागू होता है।
तीसरे चरण में ओवरलोडिंग को वैरिएबल एरिटी मेथड्स, बॉक्सिंग और अनबॉक्सिंग के साथ जोड़ा जा सकता है।
foo(null)
पहले चरण में मैच foo(Object... arg)
हुए arg = null
। arg[0] = null
तीसरा चरण होगा, जो कभी नहीं होता है।
asList
नमूने में विधि और इसके उद्देश्य को सूचीबद्ध किया था ।