1. 概述
在这个教程中,我们将探讨Java中method(String… args)
和method(String[])
的区别。我们将一起研究如何将数组或可变长度参数列表传递给方法。
2. 将数组传递给方法
在本节中,我们将展示如何在方法的参数中声明一个String
类型的数组,并在方法调用时传递相同类型的数组。
Java是一种静态类型语言,这意味着编译时就知道变量类型。程序员必须声明变量类型,无论是基本类型还是引用类型。当定义一个接受数组参数的方法时,我们期望在方法调用时明确指定要传递的数组类型。
让我们看看在方法头中定义String
数组参数的语法:
void capitalizeNames(String[] args)
上面方法头中的参数分解如下:
String[]
- 类型名args
- 参数名
void capitalizeNames(String[] args) {
for(int i = 0; i < args.length; i++){
args[i] = args[i].toUpperCase();
}
}
因此,capitalizeNames()
方法有一个String
数组参数args
。方法头说明,当调用该方法时,它只接收一个java.lang.String[]
类型的数组引用。
简而言之,当我们看到method(String[])
在方法头中时,我们应该理解这个方法在被调用时接受一个String
类型的单个数组作为参数。
看一个例子:
@Test
void whenCheckingArgumentClassName_thenNameShouldBeStringArray() {
String[] names = {"john", "ade", "kofi", "imo"};
assertNotNull(names);
assertEquals("java.lang.String[]", names.getClass().getTypeName());
capitalizeNames(names);
}
当我们检查capitalizeNames()
方法参数names
的类名时,我们得到java.lang.String[]
,这与方法定义中的参数匹配。如果我们尝试将不同类型的参数传递给方法,编译时会出错:
@Test
void whenCheckingArgumentClassName_thenNameShouldBeStringArray() {
...
int[] evenNumbers = {2, 4, 6, 8};
capitalizeNames(evenNumbers);
}
上述代码片段会在控制台上输出编译错误消息:
incompatible types: int[] cannot be converted to java.lang.String[]
3. 可变长度参数列表
Java中的可变长度参数列表(也称为varargs
)允许我们在方法调用时传递任意数量同类型的参数。
方法中可变长度参数列表的语法如下:
String[] firstLetterOfWords(String... args)
让我们分解上面方法头中的参数:
String…
- 类型名带有省略号args
- 参数名
String[] firstLetterOfWords(String... args) {
String[] firstLetter = new String[args.length];
for(int i = 0; i < args.length; i++){
firstLetter[i] = String.valueOf(args[i].charAt(0));
}
return firstLetter;
}
我们在方法签名中声明参数类型,后面跟着省略号和参数名。
使用可变长度参数列表,我们可以向方法添加任意数量相同类型的参数,因为Java将给定的参数视为数组元素处理。当在方法参数中添加varargs
时,请确保类型、省略号和参数名称放在最后。
例如,以下写法是错误的:
static String[] someMethod(String... args, int number)
我们可以通过交换参数顺序,将varargs
参数放在最后来修复这个问题:
static String[] someMethod(int number, String... args)
让我们测试上面编写的firstLetterOfWords
方法:
@Test
void whenCheckingReturnedObjectClass_thenClassShouldBeStringArray() {
assertEquals(String[].class, firstLetterOfWords("football", "basketball", "volleyball").getClass());
assertEquals(3, firstLetterOfWords("football", "basketball", "volleyball").length);
}
我们知道firstLetterOfWords()
方法接受String
类型的可变长度参数列表,因为有省略号,且我们使用了相同的参数。测试显示,当我们访问其getClass()
属性时,方法返回一个数组。当我们访问数组的长度属性时,结果为3,这与传入的参数数量匹配。
4. method(String[])
vs. method(String… args)
method(String[])
表示Java方法中的String
类型数组参数。它通常出现在Java类的主方法的参数中。主方法中的String[] args
参数将命令行参数形成一个String
数组。调用带有method(String[])
的方法时,需要提供一个String
数组作为参数。
在定义方法时,我们只能有一个可变长度参数列表。varargs
不仅限于java.lang.String
类型,还可以有其他类型,如(int… args)
、(double… args)
等。在底层,Java将使用varargs
调用方法时传递的所有参数组合成一个数组。然而,我们可以在没有参数的情况下调用带有varargs
参数的方法,这时它将被视为一个空数组。
args
作为变量名只是一个约定——可以使用任何其他合适的名称代替。
5. 总结
在这个教程中,我们探讨了method(String[])
和method(String… args)
之间的区别。前者是一个带有String
数组参数的方法,后者是一个具有可变长度参数列表(varargs
)的方法。
varargs
始终作为方法参数列表中的最后一个参数出现,因此一个方法最多只能有一个varargs
参数。
本教程的代码可以在GitHub上找到。