java基础篇 -java是值传递还是引用传递

2、java是值传递还是引用传递?

Java 有两种数据类型,一种是基本类型,比如说 int,另外一种是引用类型,比如说 String。

基本类型的变量存储的都是实际的值,而引用类型的变量存储的是对象的引用——指向了对象在内存中的地址。值和引用存储在 stack(栈)中,而对象存储在 heap(堆)中。 基本数据类型作为参数传递时,传递的是值的拷贝,无论怎么改变这个拷贝,原值是不会改变的。

在这里插入图片描述

  • 栈的优势是,存取速度比堆要快,仅次于直接位于CPU 中的寄存器。但缺点是,栈中的数据大小与生存周期必须是确定的。

  • 堆的优势是可以动态地分配内存大小,生存周期也不必事先告诉编译器,Java 的垃圾回收器会自动收走那些不再使用的数据。但由于要在运行时动态分配内存,存取速度较慢。

2.1 基本类型的参数传递

Java 有 8 种基本数据类型,分别是 int、long、byte、short、float、double 、char 和 boolean。它们的值直接存储在栈中,每当作为参数传递时,都会将原始值(实参)复制一份新的出来,给形参用。形参将会在被调用方法结束时从栈中清除。

public class PrimitiveDemo {
    public static void main(String[] args) {
        int age = 18;
        modify(age);
        System.out.println(age); // 18
    }

    private static void modify(int age1) {
        age1 = 30;
    }
}

1)main 方法中的 age 是基本类型,所以它的值 18 直接存储在栈中。

2)调用 modify() 方法的时候,将为实参 age 创建一个副本(形参 age1),它的值也为 18,不过是在栈中的其他位置。

3)对形参 age 的任何修改都只会影响它自身而不会影响实参。

在堆栈中的数据变化如下:
在这里插入图片描述

2.2 引用类型的参数传递

Writer writer = new Writer(18, "沉默王二");

writer 是对象吗?还是对象的引用?为了搞清楚这个问题,我们可以把上面的代码拆分为两行代码:

Writer writer;
writer = new Writer(18, "沉默王二");

假如 writer 是对象的话,就不需要通过 new 关键字创建对象了,对吧?那也就是说,writer 并不是对象,在“=”操作符执行之前,它仅仅是一个变量。那谁是对象呢?new Writer(18, "沉默王二"),它是对象,存储于堆中;然后,“=”操作符将对象的引用赋值给了 writer 变量,于是 writer 此时应该叫对象引用,它存储在栈中,保存了对象在堆中的地址。

每当引用类型作为参数传递时,都会创建一个对象引用(实参)的副本(形参),该形参保存的地址和实参一样。

public class PrimitiveDemo02 {
    public static void main(String[] args) {
        Writer a = new Writer(18);
        Writer b = new Writer(18);
        modify(a, b);

        System.out.println(a.getAge()); // 30
        System.out.println(b.getAge()); // 18
    }

    private static void modify(Writer a1, Writer b1) {
        a1.setAge(30);

        b1 = new Writer(18);
        b1.setAge(30);
    }
}

1)在调用 modify() 方法之前,实参 a 和 b 指向的对象是不一样的,尽管 age 都为 18。
在这里插入图片描述

2)在调用 modify() 方法时,实参 a 和 b 都在栈中创建了一个新的副本,分别是 a1 和 b1,但指向的对象是一致的(a 和 a1 指向对象 a,b 和 b1 指向对象 b)。

在这里插入图片描述

3)在 modify() 方法中,修改了形参 a1 的 age 为 30,意味着对象 a 的 age 从 18 变成了 30,而实参 a 指向的也是对象 a,所以 a 的 age 也变成了 30;形参 b1 指向了一个新的对象,随后 b1 的 age 被修改为 30。
在这里插入图片描述

修改 a1 的 age,意味着同时修改了 a 的 age,因为它们指向的对象是一个;修改 b1 的 age,对 b 却没有影响,因为它们指向的对象是两个。

修改 a1 的 age,意味着同时修改了 a 的 age,因为它们指向的对象是一个;修改 b1 的 age,对 b 却没有影响,因为它们指向的对象是两个。

引用对象参数传递时,传递的是指向真实对象的地址。

总结:
Java 的参数是以值传递的形式传⼊⽅法中,⽽不是引⽤传递。
当传递⽅法参数类型为基本数据类型(数字以及布尔值)时,⼀个⽅法是不可能修改⼀个基本数据类型的参数。

当传递⽅法参数类型为引⽤数据类型时,⼀个⽅法将修改⼀个引⽤数据类型的参数所指向对象的值。即使 Java 函数在传递引⽤数据类型时,也只是拷⻉了引⽤的值罢了,之所以能修改引⽤数据是因为它们同时指向了⼀个对象,
但这仍然是按值调⽤⽽不是引⽤调⽤

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值