当前位置: 首页 > 面试题库 >

没有传递参数或null时的Java 3点参数(varargs)行为

苏丰茂
2023-03-14
问题内容

我尝试过这个,并从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
    }

现在的问题是,如果我打电话testNull()直接与参数null,我会true回来,但如果调用callTestNull()null,它调用testNull(),它告诉我该参数不为空,但空数组。


问题答案:

问题是,如果我直接使用参数null调用testNull(),我会回来,但如果使用null调用callTestNull()调用了testNull(),它将告诉我参数不是null,而是空数组。

是。如果使用 编译时类型 为的参数调用它String,则编译器会知道它 不能String[],因此会将其包装在字符串数组中。所以这:

String x = null;
testNull(x);

等效于:

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

在这一点上,(具有误导性的)string参数将具有非null值-相反,它将引用大小为1的数组,其唯一元素是null引用。

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

从JLS第15.12.4.2节开始:

如果要调用的方法是可变Arity方法m,则它必须具有n> 0形式参数。对于某些T,m的最终形式参数必须具有T
[]类型,并且必须使用k≥0的实际参数表达式来调用m。

如果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不是null类型 时才 进行换行。



 类似资料:
  • 您可以将其他数据作为常规方法参数传递到后台任务。我再次使用下面的例子(希望没有让你厌恶): BackgroundJob.Enqueue(() => Console.WriteLine("Hello, {0}!", "world")); 在常规方法调用中,在执行后台作业期间, Console.WriteLine 方法将使用这些参数。为了参数传递进去,需要先序列化。 使用 了不起的 Newtonsof

  • 问题内容: 基本上我有一个ArrayList的位置: 在此之下,我调用以下方法: getMap()方法中的参数为: 我遇到的问题是我不确定如何在整个方法列表中传递该方法。 我试过了 但是getMap不接受,因为它不接受Objects []。 现在,如果我使用 它会完美地工作…但是我需要以某种方式传递所有位置…我当然可以继续添加等等,但是数组的大小会有所不同。我只是不习惯整个概念 最简单的方法是什么

  • 我正在实现一个存储库,该存储库实现了QuerydslBinderCustomizer,以帮助从url过滤器参数创建谓词。就是这样 我的个人实体存储库就是从这个扩展而来的, 这会产生一个endpoint 。一切正常,我可以发出请求,例如 现在,我正在实现软删除,我不想在查询时返回软删除的记录。我正计划为此编辑< code>customize方法 但是,当在没有任何参数的情况下调用endpoint时,

  • 所以我正在尝试使用、和发送一封电子邮件,并在邮件末尾添加一个取消订阅的可点击链接。这是我的方法 我可以成功发送电子邮件,但由于某种原因,在我的邮件正文中< code>unsubscribe没有显示为超链接,而是纯文本,在chrome浏览器的inspect元素中检查时,它显示如下< code >

  • 但是,如果Terminal中没有提供,我不知道如何(或者是否能够)为其设置默认值。像这样简单的东西不起作用。这里的一个解决方案是根据的内容或大小在函数中设置变量。但我不知道有没有更好的办法做到这一点。 因此,我正在寻找一种方法来使用来自终端的参数调用一个函数,其中需要一个数字(在本例中为2),而其余的是可选的,并设置为默认值。

  • 问题内容: 我有一个使用处理程序发布可运行实例的线程。它工作得很好,但是我很好奇我如何将参数传递给Runnable实例使用?也许我只是不了解此功能的工作原理。 为了避免出现“您为什么需要此问题”的问题,我有一个线程化的动画,必须调出UI线程来告诉它实际绘制的内容。 问题答案: 只需使用接受参数的构造函数实现的类就可以了, 您可以使用参数化构造函数创建Runnable类的实例。