编程Java开发者

在Java中,什么是varargs(可变长度参数),它们是如何工作的,以及使用时有什么潜在问题?

用 Hintsage AI 助手通过面试

答案

Varargs是一种语法,允许方法接收可变数量的同类型参数。通过三个点进行声明:

public void printNames(String... names) { for (String name : names) { System.out.println(name); } }

它是如何工作的?

Varargs参数在方法内部实际上是相应类型的数组:在上述示例中是String[] names。可以用任意数量的参数或数组来调用这个方法:

printNames("Igor", "Anna", "Maria"); printNames(new String[] {"Alex", "Inna"});

使用细节:

  • Varargs必须是方法参数列表中的最后一个参数。
  • 一个方法中只能有一个varargs参数。
  • 如果存在数组和varargs之间的重载,或者不同类型的varargs之间的重载,可能会导致调用的歧义。
  • 当传递null给varargs时,方法将获得null,而不是一个空数组!

诱导性问题

问题: 如果您在调用方法时不传递参数,varargs参数的数组长度将是多少?

答案: 在这种情况下,varargs变量将引用一个长度为零的数组:new String[0]。不会是null!

public void foo(Integer... args) { System.out.println(args.length); } // foo(); // 输出:0

由于对主题细节的不了解而导致的实际错误示例


故事

在日志库中有一个方法log(String... messages)。在调用log(null)时,方法内部会抛出NullPointerException(期望messages是一个空数组,而不是null)。为了解决这个问题,必须明确进行null检查。


故事

开发人员创建了重载:

public void doSomething(String[] arr) {...} public void doSomething(String... arr) {...}

在传递数组时,调用了不是预期的方法,导致部分数据丢失。数组和varargs之间的区别并不明显。


故事

在项目中在varargs之后添加了第二个参数:

public void foo(String... args, int count) {...} // 编译错误!

这导致了错误和构建中断,因为varargs必须是最后一个参数。