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

相关推荐
愚公移码7 分钟前
蓝凌EKP产品:主文档权限机制浅析
java·前端·数据库·蓝凌
Remember_99312 分钟前
【LeetCode精选算法】滑动窗口专题一
java·数据结构·算法·leetcode·哈希算法
开开心心就好20 分钟前
音频编辑工具,多端支持基础剪辑易操作
java·网络·windows·java-ee·电脑·maven·excel
Clarence Liu22 分钟前
AI Agent开发(2) - 深入解析 A2A 协议与 Go 实战指南
开发语言·人工智能·golang
凯子坚持 c26 分钟前
Protocol Buffers C++ 进阶数据类型与应用逻辑深度解析
java·服务器·c++
业精于勤_荒于稀38 分钟前
异常梳理aaaa
开发语言·qt
黎雁·泠崖39 分钟前
Java面向对象:对象内存图+成员与局部变量
java·开发语言
窗边鸟1 小时前
小白日记之java方法(java复习)
java·学习
sunfove1 小时前
实战篇:用 Python 徒手实现模拟退火算法解决 TSP 问题
开发语言·python·模拟退火算法
jiunian_cn1 小时前
【C++】IO流
开发语言·c++