java se 将参数传递下一个页面_[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 list = new ArrayList();

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 list = new ArrayList();

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 list = new ArrayList();

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 list = new ArrayList();

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 实参和形参

28a25c2fee90609fa4a5a146dc21cff3.png

实参(实际参数)

一般地,把调用方法语句中的参数,称为实参(实际参数)。

实参可以是常量、变量、对象或表达式。

形参(形式参数)

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

补充

方法调用执行的过程,其实就是将实参的数据传递给方法的形参,以这些数据为基础,执行方法完成所要表达的功能。

在实参和形参的结合上,必须保持“三一致”:

实参与形参对应的个数一致

实参与形参对应的数据类型一致

实参与形参对应的顺序一致(即 实参与形参按照顺序对应一一传递)

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

参考文献

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

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

1 Java语言与C/C++相比,参数的传递方法有所不同。

2 对于方法传递的数据类型是基本数据类型时:Java拷贝值。

3 方法接收的是原来值的一份拷贝(复制),方法接收参数的值。

(即 方法接收参数的值,但不能改变这些参数的值)

4 demo:

775057b95111690ab26278e127e8e207.png

方法调用的时候,传给方法的永远是一个值的副本,入参(即 形参)是一个新变量;

向方法传值相当于:把当前变量的值赋给入参变量;然后,入参变量的值的变动就同当前变量无关了。

a 将 自己的值1赋给变量num,方法内变量num的自增和变量a无关。

因为num的值是a的一个copy,它们没有任何内存共享的语义。

c78d1c28025a0654c56852cdaad85260.png

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

1 对于方法传递的数据类型是引用数类型,如:对象(数组也可视为一种特殊的对象)时:Java拷贝句柄(即 对象的引用地址)。

∵引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。

2 补充:数组中的元素既可是基本类型的数据,也可以是对象。

3 demo:

1b8c53659ed037d4759fb95931679207.png

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

fa6f7c5cb1a67d0b68893eaf300e7322.png

0c284cbb8c8455b5a60daf9e60152751.png

实参变量s把自己的句柄值赋值给了形参变量as。

as拿到句柄值就相当于拿到了StringBuilder实例的控制权。

所以s、as两个变量虽然是各自的句柄值,但s/as指向的是同一个对象。

所以,as的操作会影响s的结果,因为两个变量最终通过句柄指向了同一个实例。

1524f5a011246084ee0aea8635a0d2af.png

c4c15c27d9ac980e7d2e93fe36786dae.png

X 参考与推荐文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值