zoukankan      html  css  js  c++  java
  • [Java SE]Java方法的参数传递机制:值传递

    1 案例引入:实验源码

    【案例结论】

    调用方client想通过修改方法updateMethod(oldObject)调用方所在的引用对象(非基本数据类型)oldObject的属性值进行修改,则:

    • 修改方法 需保证:方法返回的引用对象调用方传入的原引用对象的引用地址(句柄)必须一致。

    object = new ClassName(); //此操作其实是对变量 object 赋予/分配新的对象地址

    关键方法: updateUser*()

    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.Set;
    
    public class MainTest {
        @Test
        public void testModifyInStreamForEachOfList1() {
            ArrayList<User> list = new ArrayList<User>();
            User user = new User();
            user.name = "wahahahhaha";
            list.add(user);
            list.stream().forEach(item -> {
                item.name = "efisgbdfjsb";// 为已设置值的字段 更新 值
                item.age = 4; // 为未设置值的字段 设置 新值
            });
            list.stream().forEach(item -> {
                System.out.println(item);
            });
            //output: name:efisgbdfjsb/tage:4
        }
    
        @Test
        public void testModifyInStreamForEachOfList2() {
            ArrayList<User> list = new ArrayList<User>();
            User user = new User();
            user.name = "wahahahhaha";
            list.add(user);
            list.stream().forEach(item -> {
                item = updateUserByOldObject(item);
            });
            list.stream().forEach(item -> {
                System.out.println(item);
            });
            //output: name:efisgbdfjsb/tage:4
        }
    
        @Test
        public void testModifyInStreamForEachOfList3() {
            ArrayList<User> list = new ArrayList<User>();
            User user = new User();
            user.name = "wahahahhaha";
            list.add(user);
            list.stream().forEach(item -> {
                updateUserByOldObject(item);
            });
            list.stream().forEach(item -> {
                System.out.println(item);
            });
            //output: name:efisgbdfjsb/tage:4
        }
    
        @Test
        public void testModifyInStreamForEachOfList4() {
            ArrayList<User> list = new ArrayList<User>();
            User user = new User();
            user.name = "wahahahhaha";
            list.add(user);
            list.stream().forEach(item -> {
                item = updateUserByNewObject(user);
            });
            list.stream().forEach(item -> {
                System.out.println(item);
            });
            //output: name:wahahahhaha/tage:0
        }
    
        public User updateUserByOldObject(User user) {//在 旧对象上做修改,然后返回
            user.name = "efisgbdfjsb";// 为已设置值的字段 更新 值
            user.age = 4; // 为未设置值的字段 设置 新值
            return user;
        }
    
        public User updateUserByNewObject(User user) {//在 new 的新对象上做修改,然后返回
            User newUser = new User();
            newUser.name = "efisgbdfjsb";// 为已设置值的字段 更新 值
            newUser.age = 4; // 为未设置值的字段 设置 新值
            return newUser;
        }
    }
    
    class User{
        public String name;
        public int age;
    
        @Override
        public String toString(){
            return "name:"+name+"/t"+"age:"+age;
        }
    }
    

    2 方法的参数传递机制

    2-1 实参和形参

    • 实参(实际参数)
      一般地,把调用方法语句中的参数,称为实参(实际参数)。
      实参可以是常量、变量、对象或表达式。

    • 形参(形式参数)
      一般地,把方法声明中的参数,称为形参(形式参数)。

    • 补充

      • 方法调用执行的过程,其实就是将实参的数据传递给方法的形参,以这些数据为基础,执行方法完成所要表达的功能。
      • 在实参和形参的结合上,必须保持“三一致”:

    实参与形参对应的个数一致
    实参与形参对应的数据类型一致
    实参与形参对应的顺序一致(即 实参与形参按照顺序对应一一传递)

    2-2 方法的参数传递机制

    参考文献

    结论:Java语言中方法的参数传递机制的本质: 值传递(仅此1种)。 [个人结论]

    2-2.1 按值传递:基本数据类型/拷贝值

    • 1 Java语言与C/C++相比,参数的传递方法有所不同。
    • 2 对于方法传递的数据类型是基本数据类型时:Java拷贝
    • 3 方法接收的是原来值的一份拷贝(复制),方法接收参数的值。
      (即 方法接收参数的值,但不能改变这些参数的值)
    • 4 demo:
    方法调用的时候,传给方法的永远是一个值的副本,入参(即 形参)是一个新变量;
    向方法传值相当于:把当前变量的值赋给入参变量;然后,入参变量的值的变动就同当前变量无关了。
    
    a 将 自己的值1赋给变量num,方法内变量num的自增和变量a无关。
    因为num的值是a的一个copy,它们没有任何内存共享的语义。
    

    2-2.2 按值传递:引用数据类型/拷贝句柄

    • 1 对于方法传递的数据类型是引用数类型,如:对象(数组也可视为一种特殊的对象)时:Java拷贝句柄(即 对象的引用地址)。
      ∵引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。
    • 2 补充:数组中的元素既可是基本类型的数据,也可以是对象。
    • 3 demo:

    String对象为不可变(final)的引用对象,每一次的赋值操作即改变一次内存地址

    实参变量s把自己的句柄值赋值给了形参变量as。
    as拿到句柄值就相当于拿到了StringBuilder实例的控制权。
    所以s、as两个变量虽然是各自的句柄值,但s/as指向的是同一个对象。
    所以,as的操作会影响s的结果,因为两个变量最终通过句柄指向了同一个实例。
    

    X 参考与推荐文献

  • 相关阅读:
    Informix日期获取上周上月昨天去年SQL
    Oracle-创建一个DBLink的方法
    Kafka-Partitions与Replication Factor 调整准则
    Linux-删除文件空间不释放问题解决
    Redhat7-Oracle-sqlldr-安装配置
    Centos7-安装oracle客户端11.2.0.4
    Centos7-单机安装jumpserver
    Redhat6.4-yum本地源安装配置
    Linux-zip unzip 命令日常使用
    xxl-job日志
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/13938500.html
Copyright © 2011-2022 走看看