Java 为什么不是引用传递

一、基本数据类型

基本数据类型:调用 modify() 方法时,是从 实参 拷贝了一份数据 给形参;修改 形参 对 实参没有任何影响

import lombok.Data;
import lombok.experimental.Accessors;

public class TransferTest{
    public static void main(String[] args) {
        testInt();
    }

    private static void testInt(){
        int i = 1;
        System.out.println("调用前:int = " + i);//调用前:int = 1
        modifyInt(i);
        System.out.println("调用后:int = " + i);//调用后:int = 1
    }

    private static void modifyInt(int i1) {
        i1 = 5;
    }

}

基本数据类型

二、引用数据类型

引用数据类型:调用 modify() 方法时,是从 实参 拷贝了一份数据的 引用 给形参;

import lombok.Data;
import lombok.experimental.Accessors;

public class TransferTest{
    public static void main(String[] args) {
        testInteger();
    }
    private static void testInteger(){
        Integer integer = new Integer(1);
        System.out.println("调用前:integer = " + integer);//调用前:integer = 1
        modifyInteger(integer);
        System.out.println("调用后:integer = " + integer);//调用后:integer = 1
    }
    private static void modifyInteger(Integer integer1) {
        integer1 = 5;
    }
}

引用类型

三、引用类型:修改 形参 属性值 与 重新赋值

1、重新赋值

import lombok.Data;
import lombok.experimental.Accessors;

public class TransferTest{
    public static void main(String[] args) {
        testUser1();
    }
    private static void testUser1() {
        User user = new User()
                .setAgeInt(1)
                .setAgeInteger(1);
        System.out.println("调用前:user = " + user);
        //调用前:user = User(ageInt=1, ageInteger=1)

        modifyUser1(user);
        System.out.println("调用后:user = " + user);
        //调用后:user = User(ageInt=1, ageInteger=1)
    }

    private static void modifyUser1(User user1){
        user1 = new User();
        user1.setAgeInt(5)
                .setAgeInteger(5);
    }
}

@Data
@Accessors(chain = true)
class User{

    private int ageInt;

    private Integer ageInteger ;

}
  1. 引用类型 实参向形参传值时,复制了 对象的引用给形参;
  2. 重新给形参赋值,就是修改形参所存储的引用;
  3. 修改形参所存储的引用地址了之后,并不会影响实参引用的指向;

引用数据类型-重新赋值

2、修改形参属性值

import lombok.Data;
import lombok.experimental.Accessors;

public class TransferTest{
    public static void main(String[] args) {
        testUser2();
     }

    private static void testUser2() {
        User user = new User()
                .setAgeInt(1)
                .setAgeInteger(1);
        System.out.println("调用前:user = " + user);
        //调用前:user = User(ageInt=1, ageInteger=1)
        modifyUser2(user);
        System.out.println("调用后:user = " + user);
        //调用后:user = User(ageInt=5, ageInteger=5)
    }

    private static void modifyUser2(User user1){
        user1.setAgeInt(5)
                .setAgeInteger(5);
    }
}
@Data
@Accessors(chain = true)
class User{

    private int ageInt;

    private Integer ageInteger ;

}

由于引用类型,在传值时,传递的是引用;所以在未改变形参引用(未重新赋值)的情况下,修改形参的属性值,实参的属性值也会改变;
修改形参属性值

3、总结

通过 setter 方法修改属性值和重新赋值的区别:
setter:未修改形参的引用地址,故形参和实参所存储的引用相同;所以形参修改了,实参也会跟着修改;
重新赋值:重新赋值,意味着形参存储的引用地址变更了;形参跟实参的所存储的引用地址不再相同,所以形参任何操作都跟实参无关;

四、值传递和引用传递的区别

我的理解是:值传递和引用传递 一个重要区别是,值传递通过 拷贝 来传递,引用传递通过 共享 来传递;这也是为什么说 Java 不是引用传递的原因;
拷贝:Java 中 基本数据类型拷贝值,引用数据类型拷贝引用地址;修改形参不会对实参造成影响
共享:实参和形参共用同一块内存地址,形参修改,实参会同时被修改;

引用传递 猜想大致图解:
引用传递 - 别名论 猜想

五、c++ 中值传递、指针传递、引用传递的区别

值传递

形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入,不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用值传递。

指针传递

我认为指针传递分为两种(猜想,如有误请指正):形参是指向实参地址的指针变量 和 形参是指向实参的 值 的地址的指针变量

1、形参是实参指向的地址的指针变量

指针传递猜想-形参是实参指向的地址的指针变量

2、形参是指向实参的 值 的地址的指针变量

Java 中引用数据类型的值传递 跟 这种指针传递类似(猜想,如有误请指正
 形参是指向实参的 值 的地址的指针变量

引用传递

形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
引用传递 - 别名论 猜想

六、愚见

  1. 值传递:是将 实参的值(值包括:基本数据类型的值和引用数据类型的地址),通过拷贝的方式传递给形参;
  2. 引用传递:是将实参的内存共享给形参,实参与形参患难与共(Java 为什么不是引用传递的原因)
  3. 指针传递:形参接收地址,实参可以传 本身的地址,也可以传 实参指针指向 的地址;猜想,如有误请指正

引用

C++ 值传递、指针传递、引用传递详解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值