【java笔记】可变长参数(...)

===============================================

 2021/4/17_第1次修改                       ccb_warlock

 

===============================================

紧接着上一篇“【c#笔记】可变长参数(params)”(https://www.cnblogs.com/straycats/p/14646210.html),我提到了整理java代码时看到了java的实现方案,故写了demo后在这做个记录。

 

java中定义的方式与c#有些不同,这里还是根据之前的目录来做记录。

 

...是什么

“...”是java用来标记是可变长类型。

 

什么时候用...

用于参数个数不确定、但类型相同的函数形参。

 

怎么用

比如下面的例子:

首先定义一个test方法,形参arrs的类型来标记这是一个可变长参数。

private void test(String... arrs)
{
    if (null == arrs || 0 == arrs.length)
    {
        System.out.println("arrs is null or empty");
        return;
    }

    for(String arr : arrs){
        System.out.println("arr is " + arr);
    }
}

 

多个参数调用如下:

test();
test("123");
test("abc", "def");

 

控制台输出:

arrs is null or empty
arr is 123
arr is abc
arr is def

 

限制条件

1)在方法声明中,只允许有一个...标记的形参类型;

2)在方法声明中,可变长参数之后不允许有其他参数;

当然在可变长参数之前可以定义其他参数,例如:

public void test(int index, String... arrs){
  // todo
}

3)由于...代表了可变长数组,不能在定义其重载函数时,定义可变长参数对应的参数为数组类型;

举例:

public void test(String... arrs){
  // todo
}

// 编译器会提示该函数在前面已定义
public void test(String[] arrs){
  // todo
}

 

FAQ

1.没有二义性的场景。

当类中有下面2个方法的定义。

public void test(String s1, String s2){
  // todo
}

public void test(String... arrs){
  // todo
}

 

此时调用函数test:

// 调用的是test(string s1, string s2)
test("123", "abc");

 

该场景没有二义性,编译器会首先匹配非可变长参数的方法。强烈建议在业务代码中不要这样定义,而是将2个函数合并成1个。

 

2.有二义性的场景。

当类中有下面2个方法的定义。

private void test(Integer... arrs){
    // todo
}

private void test(String... arrs) {
    // todo
}

 

此时调用函数test:

// 编译器报错(Ambiguous method call. )
test();

 

该场景有二义性,因为编译器无法判断该场景该选择哪个函数调用。

 

总结

测试下来,java的可变长参数和c#用法近似。

 

posted @ 2021-04-17 23:57  粽先生  阅读(58)  评论(0编辑  收藏  举报