您的位置:首页 > 其它

J2SE 5.0新特性(五)可变长参数

2011-02-09 17:46 302 查看
    可变长参数是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 )     //OK
void 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来代替重载呢?当然具体情况,具体分析。总之来说,可变长参数的推出,还是为我们的编码工作带来了很大的方便。

好了,写成这里,该出休息了......
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息