赋值操作与参数传递

本文详细探讨了Java中赋值操作与参数传递的原理,区分了基本类型和引用类型的区别。对于基本类型,赋值是值的复制,而引用类型则是引用的复制。举例说明了当两个引用指向同一对象时,通过其中一个引用修改对象,会影响另一个引用的值。同时,展示了当引用指向不同对象时,各自操作互不影响的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

误区总是有人认为Java的赋值操作和传递参数操作都是passing by value和passing by reference。这很明显是错误的,在Java中只有 passing by value。众所周知,Java有两种数据类型结构:基本数据类型与引用数据类型。那么在赋值和传参自然也只会涉及到这两种。刨根究底,在内存中,基本数据类型的值是存在栈内存中的,而引用数据类型中,它的引用也是存在栈内存中的,但是这个引用指向的对象是存在堆内存中。存储方式不同,那么在赋值和参数传递中肯定会有一些不同。

赋值与参数传递

基本类型
对基本数据类型的赋值很简单,基本类型存储了实际的数值,而并非指向一个对象的引用,所以在为其赋值的时候,是直接将一个地方的内容复制到了另一个地方.例如:对基本类型使用a=b ,那么b的内容就复制给了a.若接着又修改了a,b的值是不会受影响的。
引用类型
但是在为对象赋值的时候,情况却发生了变化,对一个对象进行操作的时候,我们真正操作的是对对象的引用。所以倘若将“一个对象赋值给另一个对象”,实际上是将“引用”从一个地方复制到了另一个地方。倘若对对象使用c=d,那么c和d都会指向原本只有d指向的那个对象。

详解

例子1:

public class Solution {

    private int a;
    private int b;

    public void setA(int a) {
        this.a = a;
    }
    public void setB(int b) {
        this.b = b;
    }
}
     Solution s1 = new Solution();
     s1.setA(1);
     s1.setB(2);
     Solution s2 = s1;
     s2.setA(-1);

设置断点,F11运行程序并打开Debug视图,在Variables一览我们可以看到s1的a,b的id与值和s2的a,b的id和值是完全一样的。
在这里插入图片描述
如果你无法理解为什么s2改变后,s1的值也会改变。那么就是引用类型和基本类型的理解不够清楚。

①:对于Solution s1 = new Solution();这条语句,这条语句执行的动作是创建一个对象,我们都很明白,但是它确包含了四个步骤:

②右边“new Solution”,表示以Solution类为模板,在堆空间中创建一个Solution类对象;
“③()”,这对括号表示,在对象创建后,会立马调用Solution类的构造函数,由于没有给参数,所以会调用默认的无参构造。
④左边的“Solution s1 ”创建了一个Solution类的引用变量,也就是说用来指向Solution对象的对象引用。这和C语言中的指针可以理解为一个意思。

这条语句包含了两个实体:一个是对象引用变量,一个是对象实体。

如上面说的s1和s2都指向了同一个对象。既然两个引用指向同一个对象,那么不管使用哪个引用操纵对象,对象的内容都发生改变,并且只有一份,通过s1和s2得到的内容自然也一样。


例子2:

package TempFile;

public class Solution {

    //基本类型的参数传递
    public static void fun1(int m){
        m = 100;
    }

    //参数为对象,不改变引用的值
    public static void fun2(StringBuffer s){
        s.append("fun2");
    }

    //参数为对象,改变引用的值
    public static void fun3(StringBuffer s){
        s = new StringBuffer("fun3");
    }

    public static void main(String[] args) {

        int i = 1;
        Solution s1 = new Solution(); 
        System.out.println(i);//i = 1
        StringBuffer ss = new StringBuffer("main");

        System.out.println(ss.toString());//main

        fun2(ss);

        System.out.println(ss.toString());//mainfun2

        fun3(ss);

        System.out.println(ss.toString());//mainfun2
    }
}

可以看到如果变量的引用是同一个对象的话,那么如果一个引用是变量发生变化,其他的引用也会随之而发生变化。如果引用的不是同一个对象,例如fun3()这个函数,由于s=new StringBuffer(),也就是s,ss此时已经指向不同的对象,那么他两自然已经没有关系了。所以不论对s做什么,ss都不会受到影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值