可变长参数是J2SE5新入的一个特性,故名思义就是可以创建数目可变的参数方法,简称varargs方法。 需要将数目不定的参数传递给一个方法的情况很常见,当然在这个新特性被引入之前,我们遇到这种情况通常情况下有两种方案来解决:一、如果需要的参数数目不大而且可知,我们可采用重载的形式来满足,每不同的参数创建不同形式的方法,这种方案有其可适用的场事,但适用范围比较窄。二、如果参数数目大而且未知,那么我们可将不定参数存储在一个集合中或数组中现传递给方法,根据一系列的判断来分离出各个参数,并加以利用,这种方案繁琐而且容易出错。
=========================Writed by Jack.Hao on 2011.01.20========================
使用可变长参数,最典型的一个例子是,printf()方法,它接受一个数目可变的参数,并将它们格式化后输出。针对以上的需求及现今的瓶颈,J2SE5引入了可变长参数的概念。 varargs特性提供了一个更简单、更好的选择。一个变长参数由三个句点(...)来指定。
例:static void varTest( String ... v )该语法告诉编译器调用varTest()的参数的数目是可变的、不确定的,可是零或更多。那么这些参数我们如何使用呢?可变长参数被隐式地转换为一个相应类型的数组对象。我们可通过数组下标的方式进行引用。下面给出一个相对完整的例子:
class VarArgs { static void varTest( String ... args ) { for( String str : args ) System.out.println( str ) ; } public static void main( String [] args ) { varTest("a","ab"); varTest("a","ab","abc"); varTest(); } }
注:1>使用可变长参数会传递的内容会被隐式封装成一个相应类型的数组,参数可有可无,如果没有参数,会被转换为一个长度为零的数组。2>varargs参数必须是方法的最后一个参数,切记!void varTest( int a , int b , String ... more ) //OKvoid varTest( int a , String ... more , int b ) //ERROR下面我们写一个变长参数与其它参数共用的情况,如下:
class VarArgs2 { static void varTest(String str , int ... more) { System.out.println( "first args:" + str ); for( int i : more ) { System.out.print( i + " " ) ; } } public static void main( String [] args ) { varTest("a",1) ; varTest("a",1,2,3); varTest("a"); varTest() ; //Error } }
=========================Writed by Jack.Hao on 2011.01.20========================
一)重载Varargs方法
根据需求,可以重载一个可变长参数的方法,来满足你的需要。如下:class VarArgs3 { static void varTest( int ... v ) { System.out.println( "Number of args:" + v.length ) ; for( int i : v ) System.out.println( i + " " ) ; System.out.println() ; } static void varTest( boolean ... bVars ) { System.out.println( "Boolean of args:" + v.length ) ; for( boolean b : bVars ) System.out.print( b + " " ) ; System.out.println() ; } static void varTest( String s , int ... iVars ) { System.out.println( "varTest( String s , int ... iVars )" ) ; System.out.println( "s=" + s ) ; for( int i : iVars ) System.out.print( i + " " ) ; System.out.println() ; } public static void main( String [] args ) { varTest(1,2,3); varTest("Test",10,20); varTest(true,false); } } 那么既然参数是不定的,重载后的方法,编译器是根据什么来指定对应的方法来执行的呢?首先vararg是根据参数类型的不同,来进行区分的。其次,如果某个重载方法增加了一个或多个正常参数,根据正常参数的数量及类型来进行区分。如果,这二种方案均不能区分出那底要用那个,那么你担心的没错,麻烦出错了,这就是我们下边要说明的一个问题,请往下看...
=========================Writed by Jack.Hao on 2011.01.20========================
二)Varargs方法的模糊性
我们接着上边的话题,如果我们对可变长参数的方法进行重载,那么可能会引出一个新的问题。如果我们对一个可变长参数方法进行了多次重载,在我们调用时,传递的参数,此时可以多个可变长参数方法的要求,那么,这时我们编译程序时,编译器就会报错,因为它无法决定到底要调用那个方法好,这种错误是由于模糊性所造成的。
如下实例:class VarArgs3 { static void varTest( int ... v ) { System.out.println( "Number of args:" + v.length ) ; for( int i : v ) System.out.println( i + " " ) ; System.out.println() ; } static void varTest( boolean ... bVars ) { System.out.println( "Boolean of args:" + v.length ) ; for( boolean b : bVars ) System.out.print( b + " " ) ; System.out.println() ; } public static void main( String [] args ) { varTest(1,2,3); varTest(true,false); varTest(); //ERROR } }如上边例子,如果我们调用varTest()无参方法时就会发生错误,因为此时varTest( boolean ... bVars )与varTest( int ... iVars)这两个重载方法都满足,那么编译器将无法决定要调那一个,就会发生模糊错误。
下边是另一个模糊型情况:static void varTest(int i )static void varTest(int i , int ... v )
以上虽然有一个重载方法使用的一个正常参数,但是当我们使用varTest(1);之样的参数进行调用时还是会发生模糊型错误,原因与上边相同,因为以上的调用完全满足那两个重载方法,所以,编译此时又不知道如何是好了。
有些时候,由于重载方法的模糊性缺陷,使我们不得不放弃变长参数方法的重载,使用两个完全不同的方法名来解决。但多数情况,我们可以从设计的角度避免掉这样事情的发生。我们可以调换正常参数的位置,比如以上情况,我们是不是可以只使用varTest(int ...v来代替重载呢?当然具体情况,具体分析。总之来说,可变长参数的推出,还是为我们的编码工作带来了很大的方便。
好了,写成这里,该出休息了......