pat*_*rit 89 java null language-design variadic-functions
如果我有一个vararg Java方法foo(Object ...arg)
并且我打电话foo(null, null)
,我有两个arg[0]
和arg[1]
作为null
s.但如果我打电话foo(null)
,arg
本身就是空的.为什么会这样?
我怎么称呼foo
这样foo.length == 1 && foo[0] == null
的true
?
Mik*_*eck 92
问题是当你使用文字null时,Java不知道它应该是什么类型.它可以是null Object,也可以是null Object数组.对于单个参数,它假设后者.
你有两个选择.将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));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
foo called, args: [a, b, c]
foo called, args: [null, null]
foo called, args: [null]
foo called, args: [null]
Run Code Online (Sandbox Code Playgroud)
Boz*_*zho 23
你需要一个明确的演员Object
:
foo((Object) null);
Run Code Online (Sandbox Code Playgroud)
否则,该参数被假定为varargs表示的整个数组.
一个测试用例来说明这一点:
带有vararg-taking方法声明的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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个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"}));
}
}
Run Code Online (Sandbox Code Playgroud)
将此作为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
为了使这更有趣,让我们receive()
从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"
}
}
Run Code Online (Sandbox Code Playgroud)
将此作为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
归档时间: |
|
查看次数: |
30340 次 |
最近记录: |