五分钟学Java:可变参数究竟是怎么一回事?

在逛 programcreek 的时候,我发现了一些专注基础但不容忽视的主题。比如说:Java 的可变参数究竟是怎么一回事?像这类灵魂拷问的主题,非常值得深入地研究一下。

以前很不重视基础,觉得不就那么回事嘛,会用就行了。就比如说今天这个主题,管它可变不可变呢,不就是个参数嘛,还能有多大学问——抱着这种态度,我一直横行江湖近十载(苦笑)。可等到读者找我提一些基础的问题时,我几乎回答不上来,感觉知识是散的,或者是浮于表面的。幸好最近一段时间,我开始幡然醒悟,开始不放过任何一个细节,渐渐地,有点“知识储备”了。

好了,牛逼吹完,让我们来步入正题。Java 的可变参数究竟是怎么一回事?

可变参数是 Java 1.5 的时候引入的功能,它允许方法使用任意多个、类型相同(is-a)的值作为参数。就像下面这样。

public static void main(String[] args) {    print("沉");    print("沉", "默");    print("沉", "默", "王");    print("沉", "默", "王", "二");}

public static void print(String... strs) {    for (String s : strs)        System.out.print(s);    System.out.println();}

静态方法 print() 就使用了可变参数,所以 print("沉") 可以,print("沉", "默") 也可以,甚至 3 个、 4 个或者更多个字符串都可以作为参数传递给 print() 方法。

说到可变参数,我想起来阿里巴巴开发手册上有这样一条规约。

意思就是尽量不要使用可变参数,如果要用的话,可变参数必须要在参数列表的最后一位。既然坑位有限,只能在最后,那么可变参数就只能有一个(悠着点,悠着点)。如果可变参数不在最后一位,IDE 就会提示对应的错误,如下图所示。

那可变参数是怎么工作的呢?

原理也很简单。当使用可变参数的时候,实际上是先创建了一个数组,该数组的大小就是可变参数的个数,然后将参数放入数组当中,再将数组传递给被调用的方法

这就是为什么可以使用数组作为参数来调用带有可变参数的方法的根本原因。代码如下所示。

public static void main(String[] args) {    print(new String[]{"沉"});    print(new String[]{"沉", "默"});    print(new String[]{"沉", "默", "王"});    print(new String[]{"沉", "默", "王", "二"});}

public static void print(String... strs) {    for (String s : strs)        System.out.print(s);    System.out.println();}

那如果方法的参数是一个数组,然后像使用可变参数那样去调用方法的时候,能行得通吗?大家感兴趣的话,不妨试一试(行不通,嘘)。

那一般什么时候使用可变参数呢?

可变参数,可变参数,顾名思义,当一个方法需要处理任意多个相同类型的对象时,就可以定义可变参数。Java 中有一个很好的例子,就是 String 类的 format() 方法,就像下面这样。

System.out.println(String.format("年纪是: %d", 18));System.out.println(String.format("年纪是: %d 名字是: %s", 18, "沉默王二"));

PS:%d 表示将整数格式化为 10 进制整数,%s 表示输出字符串。

如果不使用可变参数,那需要格式化的参数就必须使用“+”号操作符拼接起来了。麻烦也就惹祸上身了。

在实际的项目代码中,开源包 slf4j.jar 的日志输出就经常要用到可变参数(log4j 就没法使用可变参数,日志中需要记录多个参数时就痛苦不堪了)。就像下面这样。

protected Logger logger = LoggerFactory.getLogger(getClass());logger.debug("名字是{}", mem.getName());logger.debug("名字是{},年纪是{}", mem.getName(), mem.getAge());

查看源码就可以发现,debug() 方法使用的可变参数。

public void debug(String format, Object... arguments);

那在使用可变参数的时候有什么注意事项吗?

有的,有的。我们要避免重载带有可变参数的方法——这样很容易让编译器陷入自我怀疑中。

public static void main(String[] args) {    print(null);}

public static void print(String... strs) {    for (String a : strs)        System.out.print(a);    System.out.println();}

public static void print(Integer... ints) {    for (Integer i : ints)        System.out.print(i);    System.out.println();}

这时候,编译器完全不知道该调用哪个 print() 方法,print(String... strs) 还是 print(Integer... ints),傻傻分不清。

假如真的需要重载带有可变参数的方法,就必须在调用方法的时候给出明确的指示,不要让编译器去猜。

public static void main(String[] args) {    String [] strs = null;    print(strs);

    Integer [] ints = null;    print(ints);}

public static void print(String... strs) {}

public static void print(Integer... ints) {}

上面这段代码是可以编译通过的。因为编译器知道实参是 String 类型还是 Integer 类型,只不过为了运行时不抛出 NullPointerException,两个 print() 方法的内部要做好判空的操作。



好了,各位读者朋友们,以上就是本文的全部内容了。能看到这里的都是最优秀的程序员,升职加薪就是你了??。如果觉得不过瘾,还想看到更多,我再给大家推荐几篇。

Java 如何获取数组和字符串的长度?length 还是 length()?

为什么 Java 字符串是不可变的?

Java 的 substring() 是如何工作的?

如何检查Java数组中是否包含某个值 ?

原创不易,如果觉得有点用的话,请不要吝啬你手中点赞的权力;如果想要第一时间看到二哥更新的文章,请扫描下方的二维码,关注沉默王二公众号。我们下篇文章见!

原文地址:https://www.cnblogs.com/qing-gee/p/12118585.html

时间: 2024-10-01 05:04:09

五分钟学Java:可变参数究竟是怎么一回事?的相关文章

Java 可变参数

可变参数 可变参数可以当成一个数组使用 public void sum(int ...nums){ int sum = 0; for(int i:nums) { sum +=i; } System.out.println(sum); } @Test public void testSum() { sum(1,2,3,4,5); } 可变参数的实参可以是数组(同上) @Test public void testSum() { int arr[] ={1,2,3,4,5}; sum(arr); }

【Simple Java】Java可变参数举例

什么是Java可变参数 可变参数是Java 1.5引入的一个特性,它允许一个方法接受任意数量的参数. package simplejava; public class Q25 { public static void print(String... s) { for (String a : s) System.out.println(a); } public static void main(String[] args) { print("a"); print("a"

算法笔记_105:蓝桥杯练习 算法提高 上帝造题五分钟(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 第一分钟,上帝说:要有题.于是就有了L,Y,M,C 第二分钟,LYC说:要有向量.于是就有了长度为n写满随机整数的向量 第三分钟,YUHCH说:要有查询.于是就有了Q个查询,查询向量的一段区间内元素的最小值 第四分钟,MZC说:要有限.于是就有了数据范围 第五分钟,CS说:要有做题的.说完众神一哄而散,留你来收拾此题 输入格式 第一行两个正整数n和Q,表示向量长度和查询个数 接下来一行n个整数,依次对应向量中元素:a[0],a[1],

java可变参数

Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理.注意:可变参数必须位于最后一项.当可变参数个数多余一个时,必将有一个不是最后一项,所以只支持有一个可变参数.因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项. 可变参数的特点: (1)只能出现在参数列表的最后: (2)...位于变量类型和变量名之间,前后有无空格都可以: (3)调用可变参数的方法时,

Java 可变参数列表

1.可变参数列表的简单实现 当调用方法时,方法的参数个数或类型未知时,称其为可变参数列表.在以前的Java代码中,可以使用Object数组来实现这样的功能.因为,所有的类都是直接或间接继承于Object类. VarArgs.java package sample; class A1{} public class VarArgs { static void printArray(Object[] args){ for(Object obj:args) System.out.print(obj+"

java可变参数特性

可变参数:将要操作的元素作为参数传递,隐式将参数封装为数组 public static void main(String[] args) { show(1,2); show(); show1("java",1,2,3); //顺序不能变 } public static void show(int... arr) { System.out.println(arr.length); //数组长度 } public static void show1(String str,int... ar

java可变参数方法重载的注意事项

1.可变参数方法与数组参数方法重载 public class MethodParams{ //带可变参数的方法 public void hello(String ...params) { System.out.println("执行带可变参数的方法,参数个数为:" + params.length); } //带数组参数的方法 public void hello(String[] params) { System.out.println("执行带数组参数的方法,数组长度为:&q

java可变参数总结

今天总结一下java中可变参数这个知识点.还是来看一个例子,现在我想写个方法来计算两个整形的和并且输出,这个方法很简单: public class KeBian { public static void main(String[] args) { sum(5,9); } public static void sum(int a,int b) { int sum = a+b; System.out.println(sum); } } 代码很简单,没有难点,现在我想多加一个数,求三个整数的和并且输出

java可变参数列表的实现

参数就是我们调用一个方法时需要传入得数据,在方法中可能需要参数协助处理数据或者对参数进行解析处理以达到我们希望得到的数据和结果. 平常我们在写一个方法时,我们能确定需要传入什么样的参数以及参数的个数,这样我们在实现这个方法的时候在确定参数的时候都会有明确的目标.但是有时候会有这种特殊情况,我们并不知道我们将要传入几个参数,或者说我们并不确定外部会传入多少参数.在这种情况下,我们就要用到可变参数列表.下面是可变参数方法的实现方法. 1.传入数组对象或者集合,这里只对传入数组对象进行简单说明,集合的