10.java的值传递和引用传递

本文详细解释了Java中的值传递和引用传递机制,指出尽管对象参数看似像是引用传递,但实际上是值传递,因为对象的引用被传递,而非对象本身。通过实例展示了实参和形参的关系以及它们如何影响函数调用时的数据变化。
摘要由CSDN通过智能技术生成

如不了解形参与实参,请看博主9.java的实参和形参

值传递是指在调用函数时将实参复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实参。

详解:在方法的调用过程中,实参把它的实际值传递给形参,此传递过程就是将实参的值复制一份传递到函数中,这样如果在函数中对该值(形参的值)进行了操作将不会影响实参的值。因为是直接复制,所以这种方式在传递大量数据时,运行效率会特别低下。


引用传递是指在调用函数时将实参的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实参。

详解:引用传递弥补了值传递的不足,如果传递的数据量很大,直接复过去的话,会占用大量的内存空间,而引用传递就是将对象的地址值传递过去,函数接收的是原始值的首地址值。在方法的执行过程中,形参和实参的内容相同,指向同一块内存地址,也就是说操作的其实都是源数据,所以方法的执行将会影响到实际对象。

看下下面四个例子,深入了解java的值传递

public static void main( String[] args) {
     ParamTest pt = new ParamTest();
    int i = 10;
    pt.pass(i);
    System.out.println( "i is " +i);
}
public void pass(int j){
    j = 20;
    system.out.println( "j is " + j);
}

结果如下

j is 20
i is 10

public static void main(String[ ] args) {
    ParamTest pt = new ParamTest();
    User barry = new User();
    barry.setName( "Barry");
    barry.setGender("Boy");
    pt.pass(barry);
    system.out.println( "print in main , user is " + barry);
}
public void pass(User user) {
    user.setName( "Ivory");
    System.out.println( "print in pass , user is " + user);
}

结果如下

print in pass , user is User{name='Ivory', gender='Boy'}

print in main , user is User{name='Ivory' , gender='Boy'}

当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后barry持有该内存的地址,比如说是ex123456。当尝试调用pass方法,并且barry作为实际参数传递给形式参数user的时候,会把这个地址ex123456交给user,这时,user也指向了这个地址。所以当user.setName时候,会在ex123456地址上进行操作,改变了实际参数的值。

public static void main( string[] args) {
    ParamTest pt = new ParamTest();
    string name = "Barry";
    pt.pass(name ) ;
    System.out.println( "print in main , name is " + name);
}
public void pass(string name) {
    name = "Ivory";
    system.out.println( "print in pass , name is " + name);
}


结果如下

print in pass , name is Ivory

print in main , name is Barry
我们在pass方法中使用name = “Ivory”;试着去更改name的值,实际上是直接改变了name的引用的地址。因为这段代码,会new一个String,在把引用交给name,即等价于name =new String(“Ivory”);。而原来的那个”Barry”字符串还是由实参持有着的,所以,并没有修改到实际参数的值。

 

public static void main(String[ ] args){
    ParamTest pt = new ParamTest();
    User barry = new User();
    hollis.setName( "Barry");
    hollis.setGender("Boy" );
    pt.pass(barry);
    system.out.println("print in main , user is " + barry);
    public void pass(User user) {
        user = new User();
        user.setName( "Ivory");
        user.setGender( "Girl");
        system.out.println( "print in pass , user is " + user);

 结果如下

print in pass , user is User{name='Ivory' , gender='Girl'}

print in main , user is User{name='Barry', gender= 'Boy'}

当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后barry持有该内存的地址,比如说是ex123456。当尝试调用pass方法,并且barry作为实际参数传递给形式参数user的时候,会把这个地址ex123456交给user,这时,user也指向了这个地址。然后在pass方法内对参数进行修改的时候,即user = newUser();,会重新开辟一块内存,比如说是 ex456789,赋值给user。后面对user的任何修改都不会改变内存eX123456的内容。
上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在user=new User()的时候,实际参数的引用也应该改为指向ex456789,实际上并没有。这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。

 总结

Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

  • 54
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值