------- android培训java培训、期待与您交流! ----------

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

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

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

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

一、定义方法:

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

 void method(String...args) {

 }

二、调用方法:

 class VarArgsTest {
public static void method(String... str) { } public static void main(String[] args) {
method("");
method("aaa");
method("aaa", "bbb");
}
}

三、使用注意事项:

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

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

 void print(String...args) {
for (String str : args) {
System.out.println(str);
}
}

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

 class VarArgsTest {

     public void print(String... args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
} public void print(String test) {
System.out.println("----------");
} public static void main(String[] args) {
VarArgsTest test = new VarArgsTest();
test.print("hello"); //结果为----------
}
}

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

以下是错误的:

 class VarArgsTest {

     public void print(String... args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
} public void print(String test,String...args) {
System.out.println(test);
} public static void main(String[] args) {
VarArgsTest test = new VarArgsTest();
test.print("hello","hi"); //编译不通过,因为java虚拟机不知道调用哪个方法。
}
}

以下是容易犯错误的:

 class VarArgsTest {

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

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

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

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

下面是一个具体例子:

 class VarArgsTest {

     public static void main(String[] args) {

 //      sub向上转型。
Base base = new Sub();
base.print("hello"); //这里编译成功,因为涉及类型提升,调用方法时,是根据父类的参数列表来判断实参是否符合,
//而执行的是子类方法的具体内容,输出Sub......test。 // sub没有转型。
Sub sub = new Sub();
sub.print("hello"); //这里编译不成功,因为调用的是sub自身的方法,参数不符合方法中的参数列表。
}
} // 父类
class Base {
void print(String... args) {
System.out.println("Base......test");
}
} // 子类
class Sub extends Base { void print(String[] args) {
System.out.println("Sub......test");
}
}

  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对象,也就是我们定义的其他类型数组。

下面是具体例子:

 class VarArgsTest {

     public static void main(String[] args) {

 //       基本数据类型数组。
int[] arr = {1,2,4};
// 字符串数组。
String[] arr1 = {"a","b","c"};
Test t = new Test();
t.print(arr); //结果打印int数组的hashCode地址。
t.print(arr1); //结果会打印String数组中的每个元素。
t.print((Object)(arr1)); //结果会打印String数组的hashCode地址。
}
} class Test { // 可变参数类型为Object。
void print(Object... args) {
for (Object obj : args) {
System.out.println(obj);
}
}
}

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

黑马程序员_Java基础:可变参数(Varagrs)的使用注意事项的更多相关文章

  1. 黑马程序员_Java基础:反射机制(Reflection)总结

    ------- android培训.java培训.期待与您交流! ---------- 反射在java中有非常重大的意义,它是一种动态的相关机制,可以于运行时加载.探知.使用编译期间完全未知的clas ...

  2. 黑马程序员_Java基础组成

    Java语言基础组成 2.1关键字 main不是关键字,但被JVM所识别的名称. 关键字的定义和特点 定义:被Java语言赋予了特殊含义的单词. 特点:关键字中所有字母都为小写. 用于定义数据类型的关 ...

  3. 黑马程序员_Java基础视频-深入浅出精华版--PPT 文件列表

    \day01\code\第一章_Java概述.ppt;\day01\resource\资料\50道编程题(有精力的同学看看).doc;\day01\resource\资料\Sun_Java程序员认证考 ...

  4. 黑马程序员_Java基础视频-深入浅出精华版--视频列表

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  5. 课程2:《黑马程序员_Java基础视频-深入浅出精华版》-视频列表-

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  6. 黑马程序员_java基础笔记(06)...集合

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— JavaApi(其实就是java给我们提供的已经定义好的对象.工具对象:集合框架) ...

  7. 黑马程序员_Java基础:网络编程总结

    ------- android培训.java培训.期待与您交流! ---------- Java语言是在网络环境下诞生的,它是第一个完全融入网络的语言,虽然不能说它是对支持网络编程做得最好的语言,但是 ...

  8. 黑马程序员_java基础笔记(10)...JDK1.5的新特性

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 1:静态导入.2:for—each循环.3:自动装箱/拆箱.4:可变参数.5:枚举 ...

  9. 黑马程序员_java基础笔记(11)...反射

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 1,字节码.2,Constructor类.3,Field类.4,Method类.5 ...

随机推荐

  1. JavaScript prototype 使用介绍

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...

  2. android Activity绑定Service

    activity可以绑定Service,并且可以调用Service中定义的方法 Service代码:在里面多了一个IBinder;个人理解是用来与Activity绑定的主要通道: public cla ...

  3. 图情期刊要求2015(A,B,C类)

    中国图书馆学报+情报学报+大学图书馆学报+图书情报工作+图书情报知识+情报理论与实践+国家图书馆学刊+情报杂志+图书与情报+情报科学+图书馆杂志+图书馆建设+情报资料工作+图书馆论坛+现代图书情报技术 ...

  4. tomcat启动时 myeclipse控制台中文乱码

    情况1: tomcat中conf目录下有个叫server.xml的文件,里面 <Connector port="8080" protocol="HTTP/1.1&q ...

  5. Win32 OpenGL标准例子

    在VS2008的MSDN中有一个标准的OpenGL例子,记录如下: /* * Example of a Win32 OpenGL program. * The OpenGL code is the s ...

  6. Java基础之OOP

    1. 类(类型)于对象 (1)面向过程的开发于面向对象开发的区别: 面向过程更重视流程化以及功能的开发,简单点来讲,就是按照固定的模式一步步按部就班的进行,最终达成一个功能的实现.这种模式叫做面向过程 ...

  7. 分布式管理系统-git安装及配置

    安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功! 安装完成后,还需要最后一步设置,在命令行输入: $ git config - ...

  8. SQL Server 导出数据到 PostgreSQL

    乘着倒数据这会儿,把方法记录一下 需求:因为数据迁移,需要将SQL Server 2012中的数据库导入到PostgreSQL 数据库中 思路:创建一个空的数据库,便于导入数据.下载PostgreSQ ...

  9. Linux入门学习,开启端口号

    之前买了一个阿里云Centos 7服务器,默认开启22端口和80端口,想开启其他端口号如何做 1.开启端口号 [root@localhost ~]# /sbin/iptables -I INPUT - ...

  10. Cookie的Secure属性

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie ...