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

相关推荐
哎呀呀嗯呀呀8 分钟前
class 031 位运算的骚操作
java·算法·位运算
2401_8581205311 分钟前
古典舞在线交流平台:SpringBoot设计与实现详解
java·spring boot·后端
大白飞飞19 分钟前
IDEA创建、导入、删除maven项目
java·maven·intellij-idea
赐你岁月如歌23 分钟前
如何使用ssm实现基于web的网站的设计与实现+vue
java·后端·ssm
凯子坚持 c38 分钟前
C语言复习概要(四)
c语言·开发语言
何陈陈1 小时前
【Linux】线程池
linux·服务器·开发语言·c++
清风玉骨1 小时前
Qt-QHBoxLayout布局类控件(42)
开发语言·qt
2401_857297911 小时前
秋招内推2025-招联金融
java·前端·算法·金融·求职招聘
一 乐1 小时前
考研论坛平台|考研论坛小程序系统|基于java和微信小程序的考研论坛平台小程序设计与实现(源码+数据库+文档)
java·数据库·学习·考研·微信·小程序·源码
一 乐1 小时前
租拼车平台|小区租拼车管理|基于java的小区租拼车管理信息系统小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·微信·notepad++·拼车