Вызов метода Java varargs с одним нулевым аргументом?
если у меня есть метод с переменным числом аргументов в Java foo(Object ...arg)
и я называю foo(null, null)
, У меня есть оба arg[0]
и arg[1]
как null
s. но если я позвоню foo(null)
,arg
сам по себе равен нулю. Почему это происходит?
как позвонить foo
такое, что foo.length == 1 && foo[0] == null
и true
?
5 ответов:
проблема в том, что при использовании литерала null Java не знает, какой тип он должен быть. Это может быть нулевой объект или массив нулевых объектов. Для одного аргумента он предполагает последнее.
у вас есть два варианта. Приведите значение null явно к объекту или вызовите метод с помощью строго типизированной переменной. Смотрите пример ниже:
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);
в противном случае предполагается, что аргументом является весь массив, который представляет varargs.
тестовый случай, чтобы проиллюстрировать это:
код Java с объявлением метода vararg-taking (который оказывается статическим):
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чтобы сделать это более интересным, назовем