前言:
在JDK1.5中加入了可变参数,允许在调用方法时传入不定长度的参数,本质上仍是基于数组来实现的。
下面我们一起来回顾一下可变参数的常见套路吧。
1、方法定义
定义方法时,在最后一个形参后面加上三点 ...
即表示该形参可接受多个参数值,调用时多个参数被当做数组来传入:
以上示例:定义了有可变参数的方法
2、注意事项
1)可变参数只能作为最后一个参数,但前面可以没有其他参数;
2)由于只能作为最后一个参数,故每个方法只能有一个可变参数:
以上示例:无法定义多个可变参数,编译不通过!
3)JAVA中的可变参数在编译器中会被转为一个数组,可变参数在编译为字节码后,在方法签名中以数组呈现,两个方法签名上是一致的,因此不能用作重载,无法通过编译:
以上示例:本质上一样,不构成重载,编译不通过
4)可变参数可以兼容数组,反过来不成立:
以上示例:可变参数无法作为数组传入,编译不通过
3、方法重载中的可变参数
调用方法重载中,如果该调用即能和可变参方法匹配,也能和固定参数方法匹配,则优先匹配固定参数方法:
以上示例:调用了可多匹配重载方法,则优先匹配固定参数方法
4、泛型中的可变参数
JDK1.5新增的泛型机制,可以在一定条件下把一个类型参数化。
例如:我们在编写一个类的方法时,把形参的类型用标识符T来表示,类型在类初始化的时候再确定,使代码的可重用性和编译类型检查大幅提高。
需要注意的是:泛型不能和可变参数配合使用,否则会编译出错!
以上示例:泛型与可变参数配合使用时,编译不通过!
5、实例,定义可变参数,存储预关闭的IO流中的多个参数:
虽然泛型不能直接和可变参数使用,但我们仍可以通过泛型对可变参数做一个限制,例如指定可变参数的上下限,这里我们举一个上限例子:
1)定义一个关闭流工具类,借助泛型和可变参数封装一个方法:
/**
* 工具关闭流
* @author Jave Chan
*
*/
public class FileUtil {
//使用泛型方法
public static <T extends Closeable> void closeAll(T ... io) {
for (T temp : io) {
if(null!=temp) {
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2)定义一个文件拷贝的方法,最后操作关闭流时,传入带泛型的可变参数的方法关闭:
public static void copyFile(String srcPath, String desPath) throws FileNotFoundException, IOException {
//1、建立联系 源(存在且为文件) +目的地(文件可以不存在)
File src = new File(srcPath);
File des = new File(desPath);
if(!src.isFile()) {
System.out.println("只能拷贝文件");
throw new IOException("只能拷贝文件");
}
//2、选择流
InputStream fis = new FileInputStream(src);
OutputStream fos = new FileOutputStream(des, false); //true为追加,否则为覆盖,默认false
//3、文件拷贝 循环+读取+写出
byte[] bytes = new byte[1024];
int len = 0;
//读取
while(-1!=(len=fis.read(bytes))) {
//写入
fos.write(bytes, 0, len);
}
fos.flush(); //强制刷出
System.out.println("拷贝完成");
//4、关闭流,传入可变参数流
FileUtil.closeAll(fos, fis);
}
3)测试代码:
@Test
public void test() throws Exception {
String src = "D:/0225/1.txt";
String des = "D:/0225/2.txt";
copyFile(src,des);
}
4)运行结果:
总结:
以上是可变参数的点点滴滴。至于为什么要使用可变参数,一方面,我们在定义方法时可能出现无法确定要处理参数对象的个数,使用可变参数可以有效解决这个问题;
另一方面,我们在调用方法时无需再手动创建数组,提供了便利性。