深刻理解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

相关推荐
夜郎king29 分钟前
基于 Java + Playwright 实现网站自动访问与数据采集(以腾讯云开发者社区为例)
java·playwright·网页数据获取
Anastasiozzzz33 分钟前
重新定义 Agent 基建:Redis 在现代 AI 与智能体系统中的工程实践
java·人工智能·redis·ai
careathers36 分钟前
【数据结构】队列
java·数据结构
步行cgn40 分钟前
Spring 通过 factory-method 实例化 Bean 详解与常见错误排查
java·后端
lv__pf41 分钟前
seata【实战 msb】
java·开发语言·后端
点纭42 分钟前
C 语言 第七章 常用函数(3)
c语言·开发语言·算法·oracle·c#
cxoptics1 小时前
偏振片(起偏器/检偏器)怎么区分?
java
StevenLdh1 小时前
第四期 · 云端同步与冲突仲裁:离线可写、多端一致的工程解法
java·微信小程序
事已至此先睡覺吧1 小时前
第三篇:Java 流程控制详解:条件判断、循环与跳转语句
java·开发语言
毕业设计7032 小时前
(免费领源码) SpringBoot 游戏交易平台17600-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·spring boot·mysql·决策树·mybatis·idea·推荐算法