Java语法糖初探(三)--变长参数
变长参数概念
在Java5 中提供了变长参数(varargs),也就是在方法定义中可以使用个数不确定的参数,对于同一方法可以使用不同个数的参数调用。形如 function(T …args)。但是需要明确的一点是,java方法的变长参数只是语法糖,其本质上还是将变长的实际参数 varargs 包装为一个数组。
看下面的例子:
1 |
public class VariVargs {
|
将上述代码编译后,再反编译得到的结果如下:
1 |
import java.io.PrintStream; public class VariVargs |
从上面的代码可以看出java的编译器将变长参数转换成了数组,并且显示的使用了arrayOfString指向了args。后面对变长参数的操作都转换为对arrayOfString的操作。(如果变长参数是Integer型的,数组名就是arrayOfInteger。其他类型类似)
变长参数非常容易理解和使用。但是在使用过程中也会遇到一些小的陷阱,但是只要我们理解了变长参数的本质,那么都能够很容易的理解和避免这些陷阱。
变长参数规则
调用方法时能与固定参数函数以及可变参数函数都匹配时。优先调用固定参数方法
在调用方法时能与固定参数函数以及可变参数函数都匹配时,JVM会优先匹配固定参数方法,下面举一个例子:
1 |
public class VariVargsTest1 {
|
执行代码,输出:调用固定参数函数—-
调用方法时,两个变长参数函数都匹配时无法通过编译
例子如下:
1 |
public class VariVargsTest2 {
|
当没有1处代码时,程序是能够编译通过的。但是当添加了1处代码后无法通过编译,给出的错误是:The method test(String[]) is ambiguous for the type VariVargsTest2。编译器不知道选取哪个方法
一个方法只能有一个变长参数,且只能是参数列表的最后一个
由于规定变长参数只能是参数列表的最后一个。那么一个方法就不会有多个变长参数。
1 |
public class VariVargs3 {
public static void main(String[] args) {
|
在代码1处编译出错:The variable argument type String of the method test must be the last parameter
变长参数的函数重载问题
首先我们回忆一下函数重载的定义和规则
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型呢?可以相同也可以不同。
每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
重载规则:
被重载的方法必须改变参数列表
被重载的方法可以改变返回类型
被重载的方法可以改变访问修饰符
被重载的方法可以声明新的或更广的检查异常
方法能够在同一个类中或者在一个子类中被重载
变长参数与数组重载
经过上面的分析,我们知道编译器将变长参数转换为了数组,所以这两个方法的参数列表是一样的,不满足重载的第一条规则,用一个小例子证明一下:
1 |
public class VariVargsTest41 {
public static void main(String[] args) {
|
上述代码无法通过编译:Duplicate method test(String[]) in type VariVargsTest41
可变参数方法与可变参数方法重载
上面已经分析过,这里不再说明
可变参数方法与无参方法的重载
1 |
public class VariVargsTest4 {
|
输出:调用无参函数。
可变参数的重写问题
函数重写的定义和规则
重写(Override)是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。即外壳不变,核心重写!
重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。
重写规则:
参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载
返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载
访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
验证
我们先定义两个类:
1 |
public class Base {
|
1 |
public class Child extends Base{
|
Child类是Base类的子类
先看下面的测试程序:
1 |
public static void main(String []args) |
上述代码执行的输出结果是:
Base
Base
Child
base变量是Base类型的,当调用的test函数的参数只有一个时,便会调用Base类中的test(String string)方法。如果是base.test(“one”,”two”)这样调用的话,程序无法通过编译:The method test(String) in the type Base is not applicable for the arguments (String, String)
child变量是Child类型的,当调用的test函数的参数只有一个时,因为Child类继承了Base类,Child类继承了Base类中的test(String string)方法。Child有可变参数方法也有继承来的单参数方法,所以虚拟机会不管变长参数方法,而直接调用完全匹配的那个方法,输出“Base”。
总结
变长参数确实方便了我们的编程,在使用变长参数时,我们需要明确的一点是:这货就是一颗语法糖,天啊我们一直是在对数组做操作
我们在使用变长参数时,需要注意变长参数的使用规则
注意变长参数方法的重载和重写问题
参考资料
- from: https://jssyjam.github.io/2016/05/02/Java%E8%AF%AD%E6%B3%95%E7%B3%96%E5%88%9D%E6%8E%A2%EF%BC%88%E4%B8%89%EF%BC%89-%E5%8F%98%E9%95%BF%E5%8F%82%E6%95%B0-md/
Java语法糖初探(三)--变长参数的更多相关文章
- Java基础12-工具类;变长参数;IO
作业解析 取出整数的16进制表示形式 \u00ff /** * int2hex * */ public static String int2hex(int i) { String str = &quo ...
- Java语法糖详解
语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更 ...
- Java语法糖设计
语法糖 Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这 ...
- Java语法糖1:可变长度参数以及foreach循环原理
语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...
- java语法糖:(1)可变长度参数以及foreach循环原理
语法糖 语法糖:是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用 ...
- java常量和变量的定义规则,变长参数的使用
首先是定义的一般规则,类名首字母全部大写,常量全部大写用下划线分隔,变量用驼峰形式.注意使用long赋值用L时不能写小写的L要写大写的,不然会和数字“1”傻傻分不清. 下面是举例: public cl ...
- Java 语法糖详解
语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法. 这种语法对语言的功能并没有影响,但是 ...
- 深入理解java虚拟机(十二) Java 语法糖背后的真相
语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言 ...
- Java语法糖(一)
概述 语法糖(Syntactic Sugar):主要作用是提高编码效率,减少编码出错的机会. 解语法糖发生在Java源码被编译成Class字节码的过程中,还原回简单的基础语法结构. 语法糖之一:泛型( ...
随机推荐
- 001 SpringMVC的helloWorld程序
一:helloworld程序 1.结构目录 2.添加lib包 3.在web.xml中配置DispatchServlet 这个就是主servlet. <?xml version="1.0 ...
- MVC+easyui,写个树
前言:网上关于编写组织机构树的教程并不少,我第一次写树的时候也是在网上借鉴别人的技术,走了一些弯路写下了树.是因为这些教程都不是很全面,对于编程新手来说跳跃性太强.所以趁着闲暇时期,我用心的写个树,供 ...
- JAVA 画图板实现(基本画图功能+界面UI)一、界面实现
/*文章中用到的代码只是一部分,需要源码的可通过邮箱联系我 1978702969@qq.com*/ 这段时间在学JAVA的swing界面开发,试着做了个画图板.实现了直线.曲线.喷枪.矩形.圆形.文字 ...
- JAVA 图形界面开发基础详解
与C的win32一样,JAVA也有自己的图形界面开发,将在此篇博客中对基础部分进行讲解. 1.Java提供的图形界面类有哪些? Java提供了两套图形界面 (1)AWT组建(基础) AWT组件是jdk ...
- Typecho-Material主题不支持Kotlin代码高亮的解决方案
Typecho-Material主题不支持Kotlin代码高亮的解决方案 Overview 最近通过Typecho搭建了一个Blog,采用了 Material主题,其他的都挺好,也挺喜欢这个主题,但是 ...
- Android 前台服务
Android 前台服务 学习自 https://blog.csdn.net/guolin_blog/article/details/11952435#t3 前台服务漫谈 我们之前学习的Service ...
- Xamarin iOS教程之显示和编辑文本
Xamarin iOS教程之显示和编辑文本 Xamarin iOS显示和编辑文本 在一个应用程序中,文字是非常重要的.它就是这些不会说话的设备的嘴巴.通过这些文字,可以很清楚的指定这些应用程序要表达的 ...
- 添加第一个控制器(Controllers)
在MVC体系架构中,输入请求是由控制器Controller来处理的(负责处理浏览器请求,并作出响应).在ASP.NET MVC中Controller本身是一个类(Class)通常继承于System.W ...
- PDCA管理方法论
PDCA管理方法论 PDCA管理循环,由日本的高管们在1950年日本科学家和工程师联盟研讨班上学到的戴明环改造而成,最先是由休哈特博士提出来的,由戴明把PDCA发扬光大,并且用到质量领域,故称为质量环 ...
- 【转】Java类成员变量默认初始化规则
一个变量作为类成员使用的时候,如果没有被初始化,java会为其分配默认值: -------------------------------------------------------------- ...