是否可以在Java中创建一个函数来检测传递给它的任何参数是否为null? (变量)

时间:2019-06-03 20:13:59

标签: java

我想要一个函数来检测传递给它的任何参数是否为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}));
    }

已添加2019/06/04

我不知道这样做是否正确,但是我最终选择放弃varargs并尝试使用generate。

https://github.com/XenoAmess/commonx/blob/830584220a27fb3bbc1d7204cd7888e07c305b6b/src/main/java-templates/com/xenoamess/commonx/java/lang/IllegalArgumentExceptionUtilsx.java

是的,它现在可以工作,尽管很丑,也许太丑了。 不过,我想知道是否有一种平等且容易实现的方法。

2 个答案:

答案 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之外的任何外部库)