【问题标题】:Java 3 dots parameter (varargs) behavior when passed no arguments or null未传递参数或 null 时的 Java 3 点参数 (varargs) 行为
【发布时间】:2013-07-16 04:25:24
【问题描述】:

我尝试了这个并且从 JAVA 得到了奇怪的行为,有人可以为我解释一下吗?

boolean testNull(String... string) {
    if(string == null) {
        return true;
    } else {
        System.out.println(string.getClass());
        return false;
    }
}

boolean callTestNull(String s) {
    return testNull(s);
}

然后我有测试用例:

    @Test
    public void test_cases() {
        assertTrue(instance.testNull(null)); // NULL
        assertFalse(instance.testNull()); // NOT NULL
        assertFalse(instance.callTestNull(null)); // NOT NULL
    }

问题是如果我直接用参数null调用testNull(),我会得到true,但是如果用null调用callTestNull(),它调用testNull(),它告诉我参数是不是 null,而是空数组。

【问题讨论】:

标签: java variadic-functions ellipsis


【解决方案1】:

问题是如果我直接用参数null调用testNull(),我会得到true,但是如果用null调用callTestNull(),它调用testNull(),它告诉我参数不是null,而是空数组.

是的。如果您使用带有String编译时类型 的参数调用它,编译器知道不能String[],因此它将它包装在一个字符串数组。所以这个:

String x = null;
testNull(x);

相当于:

String x = null;
testNull(new String[] { x });

此时,(误导性命名的)string 参数将具有非空值 - 相反,它将引用大小为 1 的数组,其唯一元素是空引用。

但是,当您在方法调用中直接使用 null 文字时,它可以直接转换为 String[],因此不会执行包装。

来自JLS section 15.12.4.2

如果被调用的方法是一个可变数量的方法 m,它必然有 n > 0 个形式参数。对于某些 T,m 的最终形参必然具有 T[] 类型,并且 m 必然被 k ≥ 0 个实参表达式调用。

如果 m 被 k ≠ n 个实际参数表达式调用,或者,如果 m 被 k = n 个实际参数表达式调用 并且第 k 个参数表达式的类型与 T[ 的赋值不兼容],然后参数列表 (e1, ..., en-1, en, ..., ek) 被评估为好像它被写成 (e1, ..., en-1, new | T[]| { en, ..., ek }),其中 |T[]|表示 T[] 的擦除(第 4.6 节)。

(强调我的。)

我强调的一点是为什么包装在参数的编译时类型是String而不是空类型时发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 2011-11-24
    • 2022-06-11
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多