深刻理解Java中方法调用的参数传递

Java方法调用的参数传递

首先给结论:Java中均为值传递。

下面通过概念分析+代码示例的方式,实现深刻理解值传递的含义,避免死记硬背。

Java的两种数据类型

  1. 基本数据类型,比如int,double,boolean等,是从C语言中保留的类型。比如 int num = 10;在堆内存中存储结构如下:
  2. 引用数据类型,比如Object类、及其子类,String类等。即使用Class定义的类。
    比如 String str = "hello"; 在堆内存中存储结构如下:

    引用数据类型类似C中的指针。以C语言的代码来看,等价表达式为:p = "hello"。而方法调用时,传递的参数值为p,而非p;

代码示例

java 复制代码
public class Test {
    
    public String s;

    Test(String s){
        this.s = s;
    }

    public void setS(String s, Test test){
    	test.s = s;
    }

    public void setNewS(String s, Test test){
        test = new Test(test.s);
        test.setS(s);
        System.out.println("setNewS:"+test.toString());
    }

    @Override
    public String toString(){
        return "s: " + this.s;
    }
    
    public static void main(String[] args) {
        Test test = new Test("1");
        /** 步骤1:打印结果为:s: 1 **/
        System.out.println(test.toString());
        test.setS("2");
        /** 步骤2:打印结果为: s: 2 **/
        System.out.println(test.toString());
        test.setNewS("3",test);
        /** 步骤3:打印结果为:s: 2 **/
        System.out.println(test.toString());
    }
}

步骤1中打印的结果是初始值1;

步骤2,调用setS("2",test),将test实例的属性s修改为2;

步骤3,调用setNewS("3",test),test的属性为何仍旧是2呢?

原因:setNewS方法中new 了一个新对象,赋值给引用test;通过内存图像表达:

使用new 在内存中创建了一个新Test对象,后续的修改基于这个新对象,原有的对象没有任何变化,仍旧由main方法中的test引用指向着。而setNewS方法中的test引用在该方法执行后,就被清理。

关键点

我们只看被调用方法内部:

理解的关键就是看方法中有没有调用new方法创建新的对象,并且将test引用指向新的对象。

如果这样做了,那么在方法内部对test引用的任何修改都将在新对象上生效。而和老对象无关。

如果没有这么做,那么方法内部对test引用的任何修改都会在老对象生效,那么main方法中再去打印该老对象的信息自然就发生变化了。

关于基本数据类型作为参数

基本数据类型作为参数传递时,传的就是值。

比如 int i = 0; add(i)和add(0的含义是一样的。因为基本数据类型没有引用一说,只有字面量,i代表的就是0;

比如

java 复制代码
void add(int i){
	//方法内部的i是JVM新创建局部变量
	i = i + 1;
}
//方法外部的i是全局变量,不会因为add被改变
int i = 1;
add(i);
后续打印i的值仍旧为1,而不是2;

所以我们在add中对i的任何修改都不可能改变外层 i 的值;

参考

https://www.zhihu.com/question/31203609

相关推荐
珹洺10 分钟前
C++算法竞赛篇:DevC++ 如何进行debug调试
java·c++·算法
coding随想11 分钟前
掌控网页的魔法之书:JavaScript DOM的奇幻之旅
开发语言·javascript·ecmascript
SHUIPING_YANG18 分钟前
根据用户id自动切换表查询
java·服务器·数据库
爱吃烤鸡翅的酸菜鱼30 分钟前
IDEA高效开发:Database Navigator插件安装与核心使用指南
java·开发语言·数据库·编辑器·intellij-idea·database
惊涛骇浪、36 分钟前
SpringMVC + Tomcat10
java·tomcat·springmvc
墨染点香1 小时前
LeetCode Hot100【6. Z 字形变换】
java·算法·leetcode
心情好的小球藻1 小时前
Python应用进阶DAY9--类型注解Type Hinting
开发语言·python
ldj20201 小时前
SpringBoot为什么使用new RuntimeException() 来获取调用栈?
java·spring boot·后端
超龄超能程序猿1 小时前
Spring 应用中 Swagger 2.0 迁移 OpenAPI 3.0 详解:配置、注解与实践
java·spring boot·后端·spring·spring cloud
惜.己1 小时前
使用python读取json数据,简单的处理成元组数组
开发语言·python·测试工具·json