Java基础:可变参数(Varagrs)的使用注意事项

因为在先前学习java的过程中,有涉及到可变参数,但没有太深入的去学习。所以最近自己找了些相关资料,想加深了解。下面就是学习整理后的内容了。

在JDK1.5后,定义方法时,可以使用同类型个数不确定的参数。

使用可变参数定义方法时,方法实际上是把这些不确定数目的参数隐式地都装进一个数组中, 然后方法再从这个数组中取出元素来使用。

也就是说,方法使用可变参数,和JDK1.4中方法使用数组参数时的处理方式是一样的,都是取出数组元素来使用。

一、定义方法:

返回值 方法名(参数类型...可变参数名)

1 void method(String...args) {
2
3 }

二、调用方法:

 1 class VarArgsTest {
 2     public static void method(String... str) {
 3
 4     }
 5
 6     public static void main(String[] args) {
 7         method("");
 8         method("aaa");
 9         method("aaa", "bbb");
10     }
11 }

三、使用注意事项:

1.一个方法中只能有一个可变参数,并且可变参数必须位于参数列表的最后位置。否则,虚拟机无法判断传递进方法中的参数值是属于哪一个参数。

2.在方法内部可以直接把可变参数当成是数组来处理:

1 void print(String...args) {
2     for (String str : args) {
3         System.out.println(str);
4     }
5 }

3.若在类中有固定参数和可变参数的两个同名方法(重载),调用方法时的实参也可匹配它们的参数列表,会优先选择使用固定参数的方法。

 1 class VarArgsTest {
 2
 3     public void print(String... args) {
 4         for (int i = 0; i < args.length; i++) {
 5             System.out.println(args[i]);
 6         }
 7     }
 8
 9     public void print(String test) {
10         System.out.println("----------");
11     }
12
13     public static void main(String[] args) {
14         VarArgsTest test = new VarArgsTest();
15         test.print("hello");        //结果为----------
16     }
17 }

4.避免带有可变参数的方法重载。

以下是错误的:

 1 class VarArgsTest {
 2
 3     public void print(String... args) {
 4         for (int i = 0; i < args.length; i++) {
 5             System.out.println(args[i]);
 6         }
 7     }
 8
 9     public void print(String test,String...args) {
10         System.out.println(test);
11     }
12
13     public static void main(String[] args) {
14         VarArgsTest test = new VarArgsTest();
15         test.print("hello","hi");        //编译不通过,因为java虚拟机不知道调用哪个方法。
16     }
17 }

以下是容易犯错误的:

 1 class VarArgsTest {
 2
 3     public void print(String test,Integer... is) {
 4         for (int i = 0; i < is.length; i++) {
 5             System.out.println(is[i]);
 6         }
 7     }
 8
 9     public void print(String test,String...args) {
10         for (int i = 0; i < args.length; i++) {
11             System.out.println(args[i]);
12         }
13     }
14
15     public static void main(String[] args) {
16         VarArgsTest test = new VarArgsTest();
17 //      当调用print方法,只传递一个实参时,即代表传递给可变参数的实参为空null。
18 //      这时就无法从null判断可变长度参数的类型,java虚拟机不知道该调用哪个方法,发生错误。
19 //      所以在这种情况下,传递的参数如果为空,必须要通过定义变量为空的形式来确认实参的类型。
20         String str = null;
21         test.print("hello",str);
22 //      test.print("hello", null);    //编译不通过,因为java虚拟机不知道调用哪个方法。
23     }
24 }

5.子类中可用数组的形式参数列表的方法,来重写父类中带有可变参数的方法。

原因从文章开头的说明中也可知道,实际上方法是把可变参数看成是一个数组来处理的,这才导致重写成功。

这应该算一个特例,因为两个方法的参数列表是不一样的,也能实现重写。

下面是一个具体例子:

 1 class VarArgsTest {
 2
 3     public static void main(String[] args) {
 4
 5 //      sub向上转型。
 6         Base base = new Sub();
 7         base.print("hello");    //这里编译成功,因为涉及类型提升,调用方法时,是根据父类的参数列表来判断实参是否符合,
 8                                 //而执行的是子类方法的具体内容,输出Sub......test。
 9
10 //      sub没有转型。
11         Sub sub = new Sub();
12         sub.print("hello");        //这里编译不成功,因为调用的是sub自身的方法,参数不符合方法中的参数列表。
13     }
14 }
15
16 // 父类
17 class Base {
18     void print(String... args) {
19         System.out.println("Base......test");
20     }
21 }
22
23 // 子类
24 class Sub extends Base {
25
26     void print(String[] args) {
27         System.out.println("Sub......test");
28     }
29 }

6.调用带有可变参数,且参数类型为Object的方法时,传递实参是单个基本数据类型的数组,和传递单个其他类型的数组,方法会有不同的处理方式。

分别说明处理方式:

(1)基本数据类型的数组是Object的子类,当其做为实参传递给方法时,方法会把数组当成一个Object对象,接着把这个Object对象装进一个Object[]数组中,然后再从这个Object[]数组中取出元素使用。可以看出这种处理方式跟不是数组的实参传递进方法中的处理方式是一样的。

(2)其他类型的数组同样是Object的子类,当其作为实参传递给方法时,方法会认为它就是Object[]数组,不会再装进新的Object[]数组中,而是直接从这个Object[]数组中取出元素来使用。

从上面说明可以看出,区别处理的关键点在于,方法是把数组看成是一个Object对象还是一个Objuect[]数组。

基于关键点,我们传递其他类型数组的实参时,如果是希望整个数组作为一个对象来参与方法中运算,可以通过两种方式来实现。

(1)先将其他类型的数组装进一个Object[]数组中(变成二维数组),这样方法接收到实参时,就会把其当成Object[]数组处理,然后直接从这个Object[]数组中取出元素使用,这样即可实现取出的是我们定义的其他类型数组。

(2)把其他类型的数组强转成Object对象(使用(Object)),这样方法接收到实参时,会把实参当成Object对象,装进一个新的Object[]数组中,再从这个数组中取出元素使用,这样即可取出Object对象,也就是我们定义的其他类型数组。

下面是具体例子:

 1 class VarArgsTest {
 2
 3     public static void main(String[] args) {
 4
 5 //       基本数据类型数组。
 6         int[] arr = {1,2,4};
 7 //       字符串数组。
 8         String[] arr1 = {"a","b","c"};
 9         Test t = new Test();
10         t.print(arr);    //结果打印int数组的hashCode地址。
11         t.print(arr1);    //结果会打印String数组中的每个元素。
12         t.print((Object)(arr1));    //结果会打印String数组的hashCode地址。
13     }
14 }
15
16 class Test {
17
18 //   可变参数类型为Object。
19     void print(Object... args) {
20         for (Object obj : args) {
21             System.out.println(obj);
22         }
23     }
24 }

关于可变参数需要注意的地方整理得差不多了,找资料前还以为是比较简单的东西。结果才发现需要注意的东西有很多,真是学无止境啊......

时间: 2024-10-24 21:46:59

Java基础:可变参数(Varagrs)的使用注意事项的相关文章

Java基础-可变参数

大家都知道main方法的参数就是一个数组类型的,那么它其实也是可以改成不定参数类型.我试了试,并调用了一些弹出来的方法. public class ClassC2 { public static void main(String...args) { System.out.println(args.getClass()); //Exception in thread "main" class [Ljava.lang.String; System.out.println("===

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

在逛 programcreek 的时候,我发现了一些专注基础但不容忽视的主题.比如说:Java 的可变参数究竟是怎么一回事?像这类灵魂拷问的主题,非常值得深入地研究一下. 我以前很不重视基础,觉得不就那么回事嘛,会用就行了.就比如说今天这个主题,管它可变不可变呢,不就是个参数嘛,还能有多大学问--抱着这种态度,我一直横行江湖近十载(苦笑).可等到读者找我提一些基础的问题时,我几乎回答不上来,感觉知识是散的,或者是浮于表面的.幸好最近一段时间,我开始幡然醒悟,开始不放过任何一个细节,渐渐地,有点"

[问题记录]Java关于可变参数重载问题

突然发现java的可变参数重载是存在歧义的,只是不知道java内部是怎么处理的,特意做如下实验: 测试代码如下: 1 /** 2 * Created by ieayoio on 16-3-1. 3 */ 4 public class VarTest { 5 6 public static void aaa(int ...a){ 7 System.out.println("可变参数重载"); 8 } 9 10 public static void aaa(int a){ 11 Syste

java之 ------ 可变参数和卫条件

可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理. 可变参数必须位于最后一项.当可变参数个数多于一个时,必将有一个不是最后一项,所以只支持有一个可变参数. 可变参数的书写形式如: int add(int x,int ...args){  方法体 } ... 位于变量类型和变量名之间,前后有无空格都可以: 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数. 条件逻辑判断型的应用(模拟人工推理) /* 有人邀请A,B,C,D,

18、Java中可变参数

从JDK 1.5之后,Java允许定义形参可变的参数 例如: public void test(int a,String ... books){ for(String book:books){ System.out.println(book) } } 调用: test(1,"JAVA疯狂讲义","零基础javascript"); 这里的books就是一个可变参数,可以当做一个数组使用 注意: 1:可变参数必须是最后一个参数 2:一个方法中最多只能定义一个可变参数 和

Java之可变参数

Java中支持可变参数 意思就是:参数的个数可以根据需要写,你可以写1个.2个.3个....他们都被保存到一个参数的数组中. 但是这些参有一些约束:他们必须是同类型的,比如都是String字符串类型. 同时,可变参数的函数中的参数的写法也有约束:比如,可变参数的数组必须写在参数的最后,否则程序不知道你的参数到底有多少个. 例子:输出可变参数中的参数值 public class VariableArgument {    public static void main(String[] args)

c#中和java中可变参数对比

c#中可变参数用关键字params Code public class App { static void Main() { //常规使用方法 Console.WriteLine( Add( new Int32[] { 1, 2, 3, 4, 5 } ) ); //另一种调用方法 Console.WriteLine( Add( 1, 2, 3, 4, 5 ) ); //当然,参数数目是可变的,但其类型是被约束的 Console.WriteLine( Add( 1, 2, 3, 4, 5, 6,

巩固java(六)----java中可变参数方法(非常实用哦)

java提供了可变参数的方法,即方法的参数个数可以不确定,用"..."定义. import java.util.ArrayList; import java.util.List; public class VariableParameter { //求若干个整型数中的最大值 public int getMax(int... items){ //定义可变参数items int max = Integer.MIN_VALUE; //次数为int能表示的最小值,值为-2147483648 f

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中可变参数

从java5开始出现了可变参数,这是对java方法及数组的拓展! 方法中可以接受的参数不再是固定个数的,而是随着具体需求传递的多少来决定. 定义格式: 返回值类型  方法名(参数类型 ... 形式参数){    } 可变参数的特点: 只能出现在参数列表的最后: ... 位于变量类型和变量名之间,前后有无空格都可以; 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数. package reviewDemo; import java.util.Arrays