如果我有一個可變參數Java方法foo(Object ...arg)
,我呼叫foo(null, null)
,我同時使用arg[0]
和arg[1]
作爲null
s。但如果我撥打foo(null)
,arg
本身爲空。這是爲什麼發生?用單個null參數調用Java可變參數方法?
如何撥打foo
使foo.length == 1 && foo[0] == null
爲true
?
如果我有一個可變參數Java方法foo(Object ...arg)
,我呼叫foo(null, null)
,我同時使用arg[0]
和arg[1]
作爲null
s。但如果我撥打foo(null)
,arg
本身爲空。這是爲什麼發生?用單個null參數調用Java可變參數方法?
如何撥打foo
使foo.length == 1 && foo[0] == null
爲true
?
問題是,當您使用字面null時,Java不知道它應該是什麼類型。它可能是一個空對象,或者它可能是一個空對象數組。對於單個論點,它假定後者。
你有兩種選擇。將null顯式轉換爲Object或使用強類型變量調用該方法。請參見下面的示例:
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]
你需要一個顯式的Object
:
foo((Object) null);
否則該參數,則是整個陣列的可變參數代表。
不是真的,請看我的帖子。 – 2010-10-26 21:27:58
好吧,我想你錯了:) – Bozho 2010-10-26 21:30:43
哎呀,這裏也一樣...對不起,午夜油。 – 2010-10-26 21:34:30
這是因爲varargs方法可以用實際數組而不是一系列數組元素來調用。當你自己提供模糊的null
時,它假定null
是Object[]
。將null
投射到Object
將解決此問題。
測試用例來說明這一點:
的Java代碼與可變參數回吐方法聲明(這恰好是靜態的):
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;
}
}
這個Java代碼(一個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(): received 'x' is an array of size 0 sendNullWithNoCast(): received 'x' is null sendNullWithCastToString(): received 'x' is an array of size 1 sendNullWithCastToArray(): received 'x' is null sendOneValue(): received 'x' is an array of size 1 sendThreeValues(): received 'x' is an array of size 3 sendArray(): received 'x' is an array of size 3
爲了使這更有趣,讓我們調用功能在Groovy 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測試運行會產生以下結果,其中Java以粗體突出顯示。
sendNothing(): received 'x' is an array of size 0 sendNullWithNoCast(): received 'x' is null sendNullWithCastToString(): received 'x' is null sendNullWithCastToArray(): received 'x' is null sendOneValue(): received 'x' is an array of size 1 sendThreeValues(): received 'x' is an array of size 3 sendArray(): received 'x' is an array of size 3
我喜歡
foo(new Object[0]);
避免空指針異常。
希望它有幫助。
那麼,如果它是可變參數方法,爲什麼不把它叫做'foo()'呢? – 2014-03-11 00:05:22
@ BrainStorm.exe你的答案應該被標記爲答案。謝謝。 – 2016-09-28 08:28:14
如果您在示例中列出了'asList'方法及其目的,對他人有幫助。 – 2014-06-19 05:34:20
@ArunKumar'asList()'是從'java.util.Arrays'類的靜態導入。我只是假設它很明顯。雖然現在我正在考慮這個問題,但是我應該剛剛使用'Arrays.toString()',因爲它被轉換爲List的唯一原因是它會很好地打印出來。 – 2014-06-20 06:17:58