Java原来是值传递?

news/2024/11/7 23:41:09/

先说结论,Java就是值传递。

01

在Java中,所有的参数都是按值传递的,即方法得到的是所有参数值的一个副本,而不是原始参数。当我们将一个对象的引用作为参数传递给一个方法时,实际上传递的是该对象的引用的副本。

下面是一个例子来说明这一点:

public class Test {public static void main(String[] args) {int x = 10;changeValue(x);System.out.println("x = " + x); // 输出结果:x = 10String str = "hello";changeValue(str);System.out.println("str = " + str); // 输出结果:str = helloPerson person = new Person("Jack");changeValue(person);System.out.println("person.name = " + person.getName()); // 输出结果:person.name = Rose}public static void changeValue(int x) {x = 5;}public static void changeValue(String str) {str = "world";}public static void changeValue(Person person) {person.setName("Rose");}
}class Person {private String name;public Person(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

在上面的代码中,我们分别定义了三个方法changeValue,并且在main方法中调用了这三个方法。

  • 第一个changeValue方法接收一个int类型的参数,将其修改为5,但是在main方法中输出的结果依然是原来的值10,说明传递的参数是按值传递的。

  • 第二个changeValue方法接收一个String类型的参数,将其修改为world,但是在main方法中输出的结果依然是原来的值hello,说明传递的参数是按值传递的。

  • 第三个changeValue方法接收一个Person类型的参数,将其名称修改为Rose,并且在main方法中输出该对象的名称也为Rose,说明传递的参数是按值传递的。但是由于传递的是该对象的引用的副本,而不是原始参数,因此我们可以通过该引用访问和修改该对象的属性。

02

那为什么很多人都觉得Java是引用传递,比如对引用类型参数的传递?

相信这也是很多人的疑问。

产生这样的错觉,这很可能是因为Java中对象本身是通过引用来传递的。在Java中,当我们声明一个对象并将其赋值给一个变量时,实际上是创建了一个指向该对象的引用。当我们将该变量传递给一个方法时,实际上传递的是该引用,即指向该对象的地址。因此,在方法内部可以通过该引用来修改该对象的状态。

然而,需要注意的是,虽然引用本身是传递的,但是对于对象本身的修改并不会影响到原始的对象,因为传递的只是地址而不是对象本身。如果我们在方法内部将传入的参数重新赋值为一个新的对象,那么这个新对象只会存在于方法内部,并不会影响到原始的对象。

因此,我们可以说Java中是值传递,但是对于引用类型的参数,传递的是引用的值。

好的,让我们来看一个例子。

假设我们有一个Person类,其中包含姓名和年龄两个属性。现在有一个方法叫做changeAge,在该方法中,我们接收一个Person对象和一个整数作为参数,然后将这个整数赋值给Person对象的年龄属性。代码如下:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public int getAge() {return age;}
}public class Main {public static void main(String[] args) {Person p1 = new Person("Tom", 20);int newAge = 30;changeAge(p1, newAge);System.out.println(p1.getAge()); // 输出 20}public static void changeAge(Person person, int newAge) {person = new Person(person.getName(), newAge);}
}

在上面的代码中,我们创建了一个Person对象p1,其年龄为20。然后我们调用changeAge方法,并将p1和一个新的年龄值30传递给该方法。在changeAge方法中,我们通过传入的person参数来获取p1对象,并将其重新赋值为一个新的Person对象,其中年龄为传入的newAge参数。

最后,我们打印出p1对象的年龄,预期输出应该是30。但实际输出却是20。这是因为在changeAge方法中,我们只是修改了传入的person引用指向的对象,而并没有修改p1本身的值。当changeAge方法返回时,p1仍然指向原来的Person对象,其年龄还是20。

因此,我们可以看到,在Java中,虽然引用类型的参数传递的是引用的值,但是这不等同于引用传递。对于传入的引用类型参数,在方法内部对其进行修改只会影响到该引用所指向的对象,而不会影响到原始的对象。

03

看到这里,我知道有的小伙伴肯定坐不住了。

谁说不能改age,我这样写就能改!

    public static void changeAge(Person person, int newAge) {person.setAge(newAge);}

我也不多废话了,直接告诉你结论:

person仍然是值传递,传递的是引用的值(内存地址),所以看起来像引用传递。

就好像你去配了一把钥匙,也能打开门一样,但是哪怕作用一样,你手里的也是配出来的钥匙,而不是原来的钥匙。

总结

对于基本数据类型,肯定是值传递,没什么好说的。

对于引用类型,仍然是值传递,传递的是引用的值(内存地址),所以看起来像引用传递。


http://www.ppmy.cn/news/85245.html

相关文章

python 读写 json,csv,txt,docx,xlsx,xls文件大全

目录 前言一、读写json1.1 读1.2 写1.2.1 list类型写入1.2.2 dict类型写入 二、读写csv2.1 读2.2 写2.2.1 list类型写入2.2.2 dict类型写入 三、读写txt3.1 读3.2 写按行写入(手动添加换行符\n)按行写入(python添加换行符\n)3.2.1…

ThreadLocal是线程安全的吗?底层原理是什么?会存在内存泄露吗?

一、弱引用 只要垃圾回收机制一运行,不管 JVM 内存空间是否充足,都会回收该对象占用的内存。 二、ThreadLocal底层原理 ThreadLocal为共享变量在每个线程中创建一个副本,每个线程都可以访问自己内部的副本变量。通过threadlocal 保证线程的安…

【Python开发】FastAPI 01:hello world

FastAPI 是一个轻量级的后端框架,对于定制化不高或者功能简单的业务完全可以拿他作为后台。 FastAPI 一个比较重要的特性就是异步,简单来说就是相比 django 和 flask 快,FastAPI 和 flask 的语法类似。本篇文章介绍 FastAPI 运用的简单实例&a…

建设一站式DevOps平台,腾讯云研发效能提升实践

本文作者:张渝 导语 | 近年来,研发效能提升越来越受到业界重视,许多厂商都在不断探索研发效能提升之路,从而实现研发效率和质量的持续优化,以应对日趋复杂的产品开发。那么腾讯云的研发效能相关工作是如何开展和落地的…

【Python json】零基础也能轻松掌握的学习路线与参考资料

Python中的JSON模块主要用于将Python对象序列化成JSON数据或解析包含JSON数据的字符串。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。由于JSON在Web应用中的广泛使用…

EMC磁珠滤波的原理以及如何使用呢?

在产品数字电路EMC设计过程中,我们常常会使用到磁珠,那么磁珠滤波的原理以及如何使用呢? 铁氧体材料是铁镁合金或铁镍合金,这种材料具有很高的导磁率,他可以是电感的线圈绕组之间在高频高阻的情况下产生的电容最小。…

第五章matlab的自定义函数

在第三章中,我们强调了好的编程习惯的重要性。我们进行开发的基本手段是自上而 下的编程方法。在自上而下的编程方法中,它开始于对所要解决问题的精确陈述和定义输 入量和输出量。下一步,我们在大面上进行算法的描述,然后把算法分解成一个一个的子 问题。再然后,程序员把这…

Linux第一节

linux用的分区格式是 XFS EXT4 nmtui //网络使用文字显示的命令 //进去后修改IP信息 常用SSH管理工具 PC端: Mobaxterm、PuttyWinSCP、XshellXftp、SecureCRT等手机端:iTerminal、华为云APP、阿里云APP等 LINUX中补全命令,按两次tab键 在登录界面,al…