第42条:慎用可变参数

Java 1.5增加可变参数方法,可变参数方法接受0个或者多个指定类型的参数。

可变参数的机制通过先创建一个数组,数组的大小为在调用位置所传递的参数数量,然后将参数值传到数组中,最后将数组传递给方法。

static int sum(int... args) {
    int sum=0;
    for(int arg : args)
        sum += arg;
    return sum;
}

该方法如期望的那样,sum()=0,sum(1,2,3)=6

有时候,需要编写需要1个或者多个某类型参数的方法,而不是0个或者多个:

static int min(int firstArg, int... remainingArgs) {//可变参数必须放在参数列表的最后
    int min = firstArg;
    for(int arg : remainingArgs)
        if(arg < min)
            min = arg;
    return min;
}

在Java 1.5之后,Array.asList改造成可变参数方法:

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
}

在这之前,打印数组内容通常是这样的:

System.out.println(Arrays.asList(digits))

对于对象引用类型的数组,这样没有问题,但是如果是基本类型的数组,由于数组从Object继承toString实现,会打印出无意义的字符串。

这就解释为什么1.5在Arrys类中增加toString(long[]),toString(int[]),toString(short[]),toString(char[]),toString(byte[]),toString(boolean[]),toString(float[]),toString(double[]),toString(Object[]) 来提供打印数组功能。

在重视性能的情况下,使用可变参数机制要小心,因为可变参数方法的每次调用都会导致进行一次数组分配和初始化,有一种折中的解决方案,假设确定某个方法大部分调用会有3个或者更少的参数,就声明该方法的5个重载,每个重载带有0至3个普通参数,当参数数目超过3个时,使用可变参数方法。

public void foo() {}
public void foo() {int a1}
public void foo() {int a1, int a2}
public void foo() {int a1, int a2, int a3}
public void foo() {int a1, int a2, int a3, int... rest}
时间: 2024-11-07 11:29:22

第42条:慎用可变参数的相关文章

第四十二条:慎用可变参数

Java 1.5发行版本中增加了可变参数方法.可变参数方法接受0个或者多个指定类型的参数. 可变参数机制通过先创建一个数组,数组的大小为在调用位置所传递的参数数量,然后将参数值传到数组中,最后将数组传递给方法. 这样由于可变参数的方法,可变参数时借助数组实现的的,所有调用可变参数的方法时,我们可以传入若干个参数,也可以传入保存 有若干个参数的数组. 对于可变参数使用,比较典型的一个方法是:Arrays.asList(T. . .   args) 我们调用这个方法时可以这样:  List<Inte

java——慎用可变参数列表

说起可变参数,我们先看下面代码段,对它有个直观的认识,下方的红字明确地解释了可变参数的意思: 1 public class VarargsDemo{ 2 3 static int sum(int... args) { 4 int sum = 0; 5 for(int arg:args) 6 sum += arg; 7 return sum; 8 } 9 public static void main(String args[]) throws FileNotFoundException { 10

C++中的可变参数模板

作者:Eli Bendersky http://eli.thegreenplace.net/2014/variadic-templates-in-c/ 回到C++11前夜,编写带有任意参数函数的唯一办法是使用可变参数函数,像printf,使用省略号语法(-)以及伴随的va_族的宏.如果你曾经使用这个方法编写代码,你会知道这有多累赘.除了变成类型不安全外(所有的类型解析必须在运行时在va_arg里通过显式转换来完成),要做对并不容易.Va_宏执行低级的内存操作,我看见过许多因为没有小心使用它们导致

C语言可变参数函数实现原理

一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本文地址:http://www.cnblogs.com/archimedes/p/variable-parameter.html,转载请注明源地址. 例如,对于函数: void fun(int a, int b, int c) { int d; ... } 其栈结构为 0x1ffc-->d 0x200

C++11新特性之五——可变参数模板

有些时候,我们定义一个函数,可能这个函数需要支持可变长参数,也就是说调用者可以传入任意个数的参数.比如C函数printf(). 我们可以这么调用. printf("name: %s, number: %d", "Obama", 1); 那么这个函数是怎么实现的呢?其实C语言支持可变长参数的. 我们举个例子, double Sum(int count, ...) { va_list ap; double sum = 0; va_start(ap, count); fo

volatile,可变参数,memset,内联函数,宽字符窄字符,国际化,条件编译,预处理命令,define中##和#的区别,文件缓冲,位域

 1.volatile:要求参数修改每次都从内存中的读取.这种情况要比普通运行的变量需要的时间长. #include <stdio.h> #include <stdlib.h> #include <time.h> void main() { time_t start, end; double res = 0; time(&start);  //获取时间,传递给start //volatile强制每次从内存读取 volatile int i; for (i =

C# 中的可变参数方法(VarArgs)

首先需要明确一点:这里提到的可变参数方法,指的是具有 CallingConventions.VarArgs 调用约定的方法,而不是包含 params 参数的方法.可以通过MethodBase.CallingConvention 属性来获取某个方法的调用约定. 举个常见的例子来说,C 语言的 printf 方法大多数人应该都知道,它的作用是向标准输出流(stdout)写入格式化字符串,printf 的方法签名是: int printf(const char * format, ...); 方法签名

Java基础知识强化之集合框架笔记32:集合之可变参数的概述和使用

1. 可变参数的概述和使用: (1)可变参数:定义方法的时候不知道该定义多少个参数(2)格式:     修饰符  返回值类型  方法名(数据类型… 变量名){   }  注意: 这里的变量其实是一个数组 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个 2. 代码示例: 1 package cn.itcast_03; 2 3 /* 4 * 可变参数:定义方法的时候不知道该定义多少个参数 5 * 格式: 6 * 修饰符 返回值类型 方法名(数据类型… 变量名){ 7 * 8 *

黑马程序员——【Java高新技术】——JDK1.5新特性:静态导入、可变参数、增强型for循环、自动装箱拆箱、枚举

一.静态导入 1.import和import static区别: (1)import 是导入一个类或某个包中所有的类. (2)import static是导入一个类中的某个静态方法或所有的静态方法. 注:在调用静态导入的类的静态方法时,可以不用再写类名.如Arrays.sort(int[])可以直接写sort(int[]); 2.静态导入的写法: (1)import static java.util.Arrays.*;   表示导入Arrays类中的所有静态成员. (2)import stati