我想要一个函数来检测传递给它的任何参数是否为null。 如果为null,则返回true。否则为假。 我希望它是varargs。 但是有一个特殊的要求,如果我向其传递了一个不为null的Object数组,但是该数组的某些索引的某些内容为null,则我们将使此函数返回false,因为数组本身不为null。
我试图通过一些重载来解决它,但是...并不是那么容易。
public static boolean isAnyNullInParams(final Object firstObject, final Object... array) {
if (firstObject == null) {
return true;
}
if (array == null) {
return true;
}
for (Object object : array) {
if (object == null) {
return true;
}
}
return false;
}
public static boolean isAnyNullInParams(final Object[] array) {
return array == null;
}
public static boolean isAnyNullInParams() {
return false;
}
至少结果代码必须能够通过:
@Test
public void isAnyNullTest() {
Assertions.assertFalse(ArrayUtilsx.isAnyNullInParams());
Assertions.assertTrue(ArrayUtilsx.isAnyNullInParams(null));
Assertions.assertTrue(ArrayUtilsx.isAnyNullInParams(1, null));
Assertions.assertTrue(ArrayUtilsx.isAnyNullInParams(2, 2, 2, null));
Assertions.assertTrue(ArrayUtilsx.isAnyNullInParams(null, 4, 3, 3, 5));
Assertions.assertTrue(ArrayUtilsx.isAnyNullInParams(4, null, 3, 5));
Assertions.assertFalse(ArrayUtilsx.isAnyNullInParams(4, true, 3, 5));
Assertions.assertFalse(ArrayUtilsx.isAnyNullInParams(new Object[]{null, null, null}));
Assertions.assertFalse(ArrayUtilsx.isAnyNullInParams(1, new Object[]{null}));
Assertions.assertFalse(ArrayUtilsx.isAnyNullInParams(1, (Object) new Object[]{null}));
}
我不知道这样做是否正确,但是我最终选择放弃varargs并尝试使用generate。
是的,它现在可以工作,尽管很丑,也许太丑了。 不过,我想知道是否有一种平等且容易实现的方法。
答案 0 :(得分:1)
我不确定像您正在执行的重载方法是否是最佳方法。这可能是最简单的方法,但在您不得不考虑许多不同情况的地方似乎显得有些混乱。我想到的是使用Bean Validation,您将根据情况验证任何和所有方法参数。但是,这可能需要您使用AOP代理进行某种方法拦截,这可能会增加比您愿意追求的复杂性。
无论如何,为了解决您的特殊问题,我为您的特殊情况添加了另一张支票,现在所有测试都通过了:
public static boolean isAnyNullInParams(final Object firstObject, final Object... array)
{
if (firstObject == null) {
return true;
}
else if (array == null) {
return true;
}
/*
* Special case where an array contains a single null element
*/
if (array.length == 1 && array[0] == null) {
return false;
}
for (Object object : array) {
if (object == null) {
return true;
}
}
return false;
}
编辑:@VoroX指出,看来我的解决方案无法解决您的问题。我相信您需要重新考虑整个方法,也许像我在介绍中提到的那样使用Bean验证。如果您对此更感兴趣,请告诉我。
答案 1 :(得分:1)
不,这是不可能的,至少如果您提供的数组是Object[]
,这就是原因:
Object...
参数假定,如果您提供单个Object[]
,则此数组为实际参数,因此它将其值设置为vararg的值。如果您仅提供Object[]
,则:
Object... params
等于:Object[] params
。
但是,如果您提供的数组不是Object[]
,例如String[]
,则可以采用这种方法。在测试时,我发现如果您使用params.getClass().getCanonicalName()
,则会得到:
java.lang.Object[]
(如果您使用多个参数(例如containsNull(null, "Test")
),但是
java.lang.String[]
(如果您提供String[]
(例如containsNull(new String[]{null, "Test"})
)。
这是一种使用此方法的方法:
public static boolean containsNull(Object... params) {
if (params == null)
return true;
if (params.getClass().getCanonicalName().endsWith("Object[]")) {
for (Object o : params)
if (o == null)
return true;
}
return false;
}
这是一些结果:
containsNull("Test1", "Test2", 34); //Returns false
containsNull(null); //Returns true
containsNull(null, "Test"); //Returns true
containsNull(new String[]{null, "Test"}); //Returns false -> Does work with arrays
containsNull(new Object[]{"Test", null}); //Returns true! -> Does not work with Object[]
containsNull(new Object[]{"Test1", null}, "Test2"); //Returns false -> Does work with more params
(请记住,我没有考虑标准jdk之外的任何外部库)