java可变参数运用

来源:互联网 发布:淘宝上传照片尺寸 编辑:程序博客网 时间:2024/06/04 19:44
可变参数
Java 语言在 JDK1.5 中首次推出可变参数, variable arguments ,或简称 varargs 。这一新语言特征给软件开发人员在编写方法重载时提供了方便和灵活性。但可变参数的应用并不像想象的那么简单,使用时有其特殊要求和局限性。

12.7.1   重载的最好例子

读者朋友可能有这样的编程经历:在编写一个方法时,其参数随着程序运行的条件而变化,在编译期间无法确定。具体地讲,例如编写一个打印参加聚会 party 的程序,其中方法 printInvitation() 将根据作为参数的参加人姓名,打印邀请卡。但这个参数的数量事先并不确定。当然可以编写许多重载的方法来解决这个问题,如:
 
void printInvitation(String name);
void printInvitation(String name1, String name2);
void printInvitation(String name1, String name2, String name3);
...
 
问题是编写多少个重载的方法才可以解决给所有参加者打印邀请卡?也许需要改变您的程序设计,而使用数组或者链接表了。
应用可变参数可以方便、灵活地解决这类问题。例如:
 
 
void printInvitation(String...names) {
    for (String name : names) {
        makeCard(name);             // 调用方法按照姓名打印邀请卡
        System.out.println("Recording info: invitation card has been printed for " + name);
    }
}
 
这里, (String...names) 便是可变参数。它包括从 0 到任意个相同类型的参数。在编译期间,这个可变参数将被转换为字符串数组形式,即:
 
void printInvitation(String[] names)
 
如下是调用这个方法的例子:
 
printInvitation(" 李刚 ", "David Smith");
printInvitation("Greg Wu", "Paul Nguyen", "Liu Wei", " 张新 ") ;
printInvitation();          // 无参数
 
当在无参数情况下调用这个方法时,将不执行任何这个方法中的代码。
如下是运行结果:
 
Recording info: invitation card has been printed for 李刚
Recording info: invitation card has been printed for David Smith
Recording info: invitation card has been printed for Greg Wu
Recording info: invitation card has been printed for Paul Nguyen
Recording info: invitation card has been printed for Liu Wei
Recording info: invitation card has been printed for 张新

12.7.2   怎样工作

       可变参数也不神秘。实际上, JVM 将根据程序中调用这个方法时提供的参数数量,来装载和运行它。
       可变参数的简单语法格式为:
 
methodName([argumentList], dataType...argumentName);
 
       其中:
       argumentList ——普通参数,可选项。
       dataType ——数据类型或者类。自动转换成 dataType 代表的数组。
       ... —— Java 的操作符。表示 0 到多个。必须是 3 个点。
       argumentName ——参数名。
       注意,可变参数必须在最后。
       下面是应用可变参数的更多例子:
 
 
public static int sumInts(int...numbers) {  // 可变整数数组类型参数
    int sum = 0;
    for (int num : numbers)
        sum +=num;
    return sum;
}      
 
       再如:
 
public void totalTax(String name, double rate, double...amount) {  
                                            // 普通参数在前、可变参数在后
    double total = 0.0,
           tax = 0.0;
    for (double amount : amounts)
        total += amount;
    tax = total *  rate;
    System.out.println("Name: " + name + "\nTotal: " + total + "\ntax: " + tax);
}
 
       可变参数也可应用在构造器中。例如:
 
public class Supper {
    public Supper(char...characters) {
    ...
    }
 
       在子类中,可以覆盖这个构造器,如:
 
class SubClass extends Supper {
    public SubClass(char...characters) {
        ...
    }
}
 
       但无法在子类中调用超类的这个构造器。
      更多信息   可变参数可以用在构造器中,并可以覆盖。

12.7.3   可变参数方法重载

       可以对具有可变参数的方法重载。如下例子:
 
void someMethod(int count, double...prices) {
    // 语句体
    ...
    }
void someMethod(double...prices) {              // 重载
    // 语句体
    ...
    }
double someMethod(String...names) {             // 重载
    // 语句体
    ...
}
...

  对方法someMethod()实行重载。对具有可变参数的方法重载遵循一般方法重载原则。
enum ColorType {
    WHITE {String getDescription(){
                return "有浅白、暗白、和亮白可选";
            }
    },
    SILVER {String getDescription() {
                return "有银白、银灰、纯银色可选";
            }
    },
    BLACK {String getDescription() {
                return "有深黑和浅黑可选";
            }
    };
    abstract String getDescription();
}
enum PaymentType {
    CASH("有10%特别优惠"),
    CREDIT("接受所有信用卡"),
    LOAN("贷款利息为.56%");
    final private String payment;
    private PaymentType(String payment) {
        this. payment = payment;
    }
    public String getPayment() {
        return payment;
    }
}
 
另外,在SportCar中,根据用户的选择,加入了对跑车类型、颜色,以及付款方式的处理方法,并且利用可变参数。例如:
 
class SportCar {
    SportCarType type;                      //创建
    ColorType color;
    PaymentType payment;
    public SportCar (String...choices) {    //可变参数
        type = null;                        //初始化
        color = null;
        payment = null;
        processInfo(choices);               //调用处理信息方法
   }
   private void processInfo(String[] choices) {
       if (choices.length == 1) {           //处理跑车类型
          processType(choices[0]);
        }
       else if (choices.length == 2) {      //处理跑车类型和颜色
         processType(choices[0]);
         processColor(choices[1]);
        }
       else if (choices.length == 3) {      //处理跑车类型、颜色和付款方式
         processType(choices[0]);
         processColor(choices[1]);
         processPayment(choices[2]);
       }
 }
 private void processType(String type) {    //处理类型
        if (type.equals("P"))
            this.type = SportCarType.PORSCHE;
        else if (type.equals("F"))
           this.type = SportCarType.FERRARI;
        else if(type.equals("J"))
            this.type = SportCarType.JAGUAR;
}
...
 
这个类的驱动程序如下:
 
public class VarargsApp {
   public static void main( String args[] ) {
     SportCar yourCar = new SportCar("P");          //创建一个参数的对象
     System.out.println("你要的跑车信息:\n" + yourCar + "\n");
 
     SportCar myCar = new SportCar("J", "S");       //创建两个参数的对象
     System.out.println("我要的跑车信息:\n" + myCar + "\n");
 
     SportCar herCar = new SportCar("F", "B", "C");//创建三个参数的对象
     System.out.println("她要的跑车信息:\n" + herCar + "\n");
    }
}
 
运行结果如下:
 
你要的跑车信息:
制造国:德国
价格:$120,000.00
 
我要的跑车信息:
制造国:英国
价格:$110,000.00
有银白、银灰、纯银色可选
 
她要的跑车信息:
制造国: 意大利
价格:$150,000.00
有深黑和浅黑可选
有10%特别优惠
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 发际线掉头发怎么办偏方 头上脓包掉头发怎么办 小孩头发少又黄怎么办 发旋哪里头发少怎么办 每次洗头发都掉好多怎么办 10岁儿童掉头发怎么办 1岁半宝宝掉头发怎么办 头发掉发严重怎么办吃什么 掉了一块钱很气怎么办 头发软又少怎么办盘头 头发出油掉的厉害怎么办 头发很油又少怎么办 18岁头发发量少怎么办 头发少长的慢怎么办 额头大发际线高怎么办 前额两边的头发变少了怎么办 吃减肥药掉头发怎么办 牙长智齿吃饭疼怎么办 头发稀少容易掉发怎么办 大把掉发头发稀少怎么办 头发掉厉害洗生发灵更掉怎么办? 额头两侧和头顶头发少怎么办 额头前面头发少怎么办天生的 头两边的碎头发怎么办 30岁后头发少怎么办 生完孩子头发少怎么办 1岁宝宝头发少怎么办 头顶上的头发少怎么办呢 22岁头顶头发稀少怎么办 头发又稀又少怎么办 头顶的头发越来越少怎么办 四岁宝宝头发稀少怎么办 一岁宝宝头发稀少怎么办 三岁宝宝头发稀少怎么办 头发油急着出门怎么办 长出的头发毛糙弯曲怎么办 头发薄还掉头发怎么办 头发少掉的厉害怎么办 一洗头就掉很多头发怎么办 生完孩子掉头发怎么办 甲减引起的肥胖怎么办