java是值传递还是引用传递

文章详细阐述了Java中的值传递和引用传递概念,以及它们与值类型和引用类型的关系。值传递在方法传参时不会影响原内容,而引用传递(实际上是引用副本的传递)在某些情况下看似能影响原内容,但Java本质上只有值传递。文章通过示例代码解释了这一现象,并指出所有对象实例和数组都在堆上分配,栈中仅存储引用。
摘要由CSDN通过智能技术生成

说到值传递和引用传递我们不得不提到两个概念:值类型和引用类型。

1.值类型

通俗意义上来说,所谓的值类型指的就是 Java 中的 8 大基础数据类型:

整数型:byte、int、short、long
浮点型:float、double
字符类型:char
布尔类型:boolean
在这里插入图片描述

从 JVM 层面来讲:所谓的值类型指的是在赋值时,直接在栈中(Java 虚拟机栈)生成值的类型

2.引用类型

引用类型是指除值类型之外的数据类型,比如:


接口
数组
字符串
包装类(Integer、Double…)
图片

从 JVM 的层面来讲,所谓的引用类型是指,在初始化时将引用生成栈上,而值生成在堆上的这些数据类型,如下图所示:

在这里插入图片描述

3.值传递

值传递(Pass By Value)指的是方法传参时,传递的是原内容的副本,因此对副本进行如何修改都不会影响原内容。

实现代码如下:

  public static void test(int  processCode) {
        processCode = 10;
        System.out.println("方法中更改:"+processCode);
    }
   public static void main(String[] args) {
        int processCode = 5;
        System.out.println("更改前的code:"+processCode);
        test(processCode);
        System.out.println("更改后的code:"+processCode);

    }

程序的执行结果为:

在这里插入图片描述

从上述结果可以看出,在方法中修改参数并未影响原内容,我们把这种传参方式称之为值传递。

4.引用传递

引用传递(Pass By Reference)指的是方法传参时,传递的是参数本身,因此对参数进行任意修改都会影响原内容。

模拟“引用传递”的实现代码如下:

     public static void test(JSONObject obj ){
            obj.put("test1",456);
            System.out.println("方法中更改:"+obj);

    }
   public static void main(String[] args) {
        JSONObject obj = new JSONObject();
        obj.put("test",123);
        System.out.println("更改前的code:"+obj);
        test(obj);
        System.out.println("更改后的code:"+obj);

    

程序的执行结果为:
在这里插入图片描述

从上述的结果可以看出在 paramTest 方法中修改了参数之后,在 main 方法中再打印参数时,发现参数的值也跟着发生了改变,那么似乎我们可以得出结论,Java 中貌似也有“引用传递”,然而实事并如此,我们接着看。

5.真假“引用传递”

我们给上面的代码添加一行,如下所示:

    public static void test(Object obj ){
            obj = new Object();
            System.out.println("方法中更改:"+obj);

    }
  public static void main(String[] args) {
        Object obj = null;
        System.out.println("更改前的code:"+obj);
        test(obj);
        System.out.println("更改后的code:"+obj);

    }

程序的执行结果为:
在这里插入图片描述

从上述结果可以看出,当我们在test 方法中添加 new Object()之后,“引用传递”就突然变值传递了?为什么?

这是因为,在 Java 语言中本质上只有值传递,也就说 Java 的传参只会传递它的副本,并不会传递参数本身。

前面那个带引号的“引用传递”其实只是传递了它的引用副本,如下图所示:

图片

PS:《Java虚拟机规范》中对 Java 堆的描述是:“所有的对象实例以及数组都应当在堆上分配”。
所以我们在调用 new Object()之后,可以看出 对象有了新地址,而原内容并未被修改,如果按照引用传递的思路来看的话,不管执行任何方式的修改都会改变原内容,因此我们可以更加确认 Java 语言中只有值传递

总结

通过本文的内容,我们可以得出:在 Java 语言中只有值传递,方法传参时只会传递副本信息而非原内容。我们还知道了基础数据类型会直接生成到栈上,而对象或数组则会在栈和堆上都生成信息,并将栈上生成的引用,直接指向堆中生成的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值