第9篇 方法知识点综合(求值策略与可变参数)

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 把传对象也认为是传值,应该把其归类为传值调用。其实也很好理解:

  1. new 出来的对象是地址映射型的,[key] [addr]。把该实参的本质当作是一种映射关系
  2. 把地址复制过去的这一步不就是在赋值映射关系吗,这也就成了传值调用。
  3. 一句话:共享对象传递就是值传递,传递的值是对象的引用
1.1.2 总结

总之,在Java方法传参时,无论传递的参数是基本类型还是引用类型,都是值传递!切记一点,Java里面只有值传递,没有引用传递!

1.2 非严格求值策略

2.可变参数

Java中的方法是可以带有多个参数的,理论上是可以无限个。但实际上一个方法的参数最好不要超过5个。在Java 5中提供了一个可变长参数,该参数允许我们在调用方法时传入不定长度的参数。其实本质上是基于数组来实现的。所以当我们不确定一个方法需要处理的参数个数时,都可以使用可变长参数。

方法名(形参1, 形参2, ...){} // 此处点点点就是可变参数的意思
  • 可变参数的格式,就是在方法最后一个形参的后面加上三个点 “…“,表示该形参可以接受 0个参数值, 也可以是1个或者多个参数值,多个参数值会被当成数组传入。

  • 可变参数只能作为方法的最后一个参数,该参数的前面可以有也可以没有其他参数

  • 由于可变参数必须是 最后一个参数,所以一个方法最多只能有一个可变参数

  • Java的可变参数,会被编译器转型为对应类型的数组

  • 可变参数在编译为字节码后,在方法签名中是以数组形态出现的。这两个方法的签名是一致的,不能作为方法的重载。如果同时出现,是不能编译通过的。可变参数可以兼容数组,反之则不成立。

  • 可变参数与其他参数列表非数组的同名方法构成重载

public static void main(String[] args) {} //不兼容下面式子
public static void main(String... args) {} //兼容上式子,等价于上式
public class A{
//已有可变参数的方法
void fun(int... a){}
//验证重载可行性
void fun(int a ){}//成功重载
void fun (int a , int b){}//成功重载
void fun(int a,int... a ){}//成功重载,不建议
void fun(int[] a){}//重载失败
}
posted @   问稻  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示