1. 求值策略
编程语言中方法之间进行参数传递时有个传递策略,该策略就被称为求值策略(Evaluation strategies)。求值策略分为两大基本类型,如果按照如何处理传递给方法的实际参数,分为严格的和非严格的两种求值策略。
1.1 严格求值策略
-
传值调用(Call by value)
将实参复制一份给形参,修改形参不会对实参造成影响。形式参数拿到的只是一个"局部拷贝"。
-
传引用调用(Call by reference)
在方法调用时将引用类型的实参地址值 复制 一份传递给形参,相当于形参和实参指向了同一个内存地址。引用传递会将实参的地址传递给形参,修改形参也就是在修改实参。
-
传共享对象调用(Call by sharing)
在传共享对象调用中,先获取到实际参数的地址,然后将其复制,并把该地址的拷贝传递给被调方法的形式参数。因为参数的地址都指向同一个对象
注意:
- 用类类型做形参时c++是调用拷贝构造函数创建整个类的副本,所以不会影响原值。
- java 用类类型做形参时, 传的是原值的地址,修改形参会影响原值
public class ShareObject { public static void main(String[] args) { //待共享对象 ShareObject shObj= new ShareObject(10); System.out.println("修改前的值"+ shObj.geti());//修改前的值10 // changeByShareObject(shObj); System.out.println("通过共享对象传递修改后的值"+ shObj.geti());//通过共享对象传递修改后的值20 /* * 1.创建了一个共享对象的类 shareObject,该类包含了一个私有成员变量i, * 2.调用 changeByShareObject 方法传递了 shObj 的引用在该方法中,修改了 i 的值为20. * 3.比较调用 changeByShareObject(ShareObject Obj) 前后 i 的值可以得出 Obj 可以改变 shObj 中 i 的值 * */ } private int i;//私有实例变量 public void seti(int value){ this.i=value;//通过方法修改实例变量的值 } public int geti(){ return this.i; } public ShareObject(int value){ this.i=value;//构造函数 } public static void changeByShareObject( ShareObject Obj){ Obj.seti(20);//共享对象调用改值 } }
1.1.1 传共享对象调用 到底是 传值调用 还是 传引用调用 的特例
从过程来看,都是复制了实参的地址传给形参,通过修改形参也可以实现修改实参。所以 传共享对象调用 会是传引用调用吗?
《The Java™ Tutorials》中Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object’s fields can be changed in the method, if they have the proper access level.
java 把传对象也认为是传值,应该把其归类为传值调用。其实也很好理解:
- new 出来的对象是地址映射型的,[key] [addr]。把该实参的本质当作是一种映射关系
- 把地址复制过去的这一步不就是在赋值映射关系吗,这也就成了传值调用。
- 一句话:共享对象传递就是值传递,传递的值是对象的引用
1.1.2 总结
总之,在Java方法传参时,无论传递的参数是基本类型还是引用类型,都是值传递!切记一点,Java里面只有值传递,没有引用传递!
1.2 非严格求值策略
2.可变参数
Java中的方法是可以带有多个参数的,理论上是可以无限个。但实际上一个方法的参数最好不要超过5个。在Java 5中提供了一个可变长参数,该参数允许我们在调用方法时传入不定长度的参数。其实本质上是基于数组来实现的。所以当我们不确定一个方法需要处理的参数个数时,都可以使用可变长参数。
方法名(形参1, 形参2, ...){} // 此处点点点就是可变参数的意思
-
可变参数的格式,就是在方法最后一个形参的后面加上三个点 “…“,表示该形参可以接受多个参数值,多个参数值会被当成数组传入。
-
可变参数只能作为方法的最后一个参数,该参数的前面可以有也可以没有其他参数
-
由于可变参数必须是最后一个参数,所以一个方法最多只能有一个可变参数
-
Java的可变参数,会被编译器转型为对应类型的数组
-
可变参数在编译为字节码后,在方法签名中是以数组形态出现的。这两个方法的签名是一致的,不能作为方法的重载。如果同时出现,是不能编译通过的。可变参数可以兼容数组,反之则不成立。
public static void main(String[] args) {} //不兼容下面式子
public static void main(String... args) {} //兼容上式子,等价于上式
标签:知识点,Day09,调用,形参,传递,参数,可变,求值,实参
From: https://www.cnblogs.com/wendao101/p/17875534.html