`

从堆和栈的角度看参数传递

阅读更多
在java中,参数的传递方式只有一种:值传递。但是这个“值”的的含义我们不能单从字面理解。确切的说它分为两种:一个是基本类型的值传递,一个是对象的值传递。

对于基本类型来讲,值传递很容易理解,就是把实参的的值传递给形参,例如
public static void add(int a) {
		a = a + 3;
		System.out.println(a);
	}
	
public static void main(String[] args) {
		int a = 3;
		add(a);
		System.out.println(a);	
       }

这段代码的输出为:6,3
当运行到main方法的时候,在栈中会给main()方法分配一个内存空间用来存放局部变量 ,也就是实参a;当调用add()方法时,栈又会给add() 方法分配一个内存空间,存放add方法中的局部变量,也就是形参 a。当调用add方法时,我们改变的只是形参的值,实参的值并没有改变,因为它们处于不同的内存地址。

将对象作为参数来传递时,虽然本质也是值传递,但这个值并不是对象本身,而是传递的引用,也就是这个对象在堆中的地址。例如下面我们创建了一个Animal类:
public class Animals {
	private String color;
	public Animals(String color) {
		this.color = color;
	}
	
	public static void setColor(Animals animal) {
		animal.color = "black";
		System.out.println(animal.color);
	}
	public static void main(String[] args) {
		Animals dog = new Animals("white");
		setColor(dog);
		System.out.println(dog.color);
	}
}

这段代码的输出是:black,black
首先我们在main方法中实例化了一个Animals对象dog,并初始化它的颜色为白色的,正如我们前面讲的,具体的对象保存在堆中,dog是个引用变量,内容是这个对象在堆中的地址。当我们调用setColor方法时,我们把dog的这个引用变量里面的内容复制给animal这个形参,此时它们指向同一个对象,一次当我们通过形参animal改变对象的属性时,对象本身发生了变化,只要指向这个对象的引用都收到了影响,从而我们在用这个引用访问对象时,就会发生变化。

总结:java中参数的传递是值传递,形参和实参占用了不同的内存空间,只是在传递基本类型和对象时这个“值”的含义不同而已。
分享到:
评论

相关推荐

    Java中的JVM基础-数据类型和堆栈_.docx

    第一,从软件设计的角度看,栈代表了处理规律,而堆代表了数据。这样分开,使得处理规律更为清楚。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。其次,堆与栈的分别,使得堆中的内容可以被...

    jvm内部结构大解密

    第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。第二,堆与栈的分离,使得堆中的内容可以被...

    ActivityGroup实现Activit栈

    尽管ActivityGroup已经被淘汰,但我们仍然可以从历史的角度来理解它的运作机制和一些关键知识点。 1. **ActivityGroup的生命周期**: - ActivityGroup内部管理的子Activity并不直接遵循正常的Activity生命周期。当...

    从C/C++角度探秘计算机系统(完整版)

    本书深入剖析了内存区域划分,包括栈区、堆区、静态区和代码区等,并解释了每个区域的特点及应用场景。此外,书中还详细探讨了C/C++中的指针概念,包括指针的基本操作、指针与数组的关系、指针与函数等,帮助读者...

    编译原理:第9章 运行阶段存储组织与分配.pdf

    其次,从存储分配的角度来看,主要有静态存储分配和动态存储分配两种方案。静态存储分配的方案是在编译阶段为所有的数据对象分配固定的存储空间,运行时刻存储单元大小不变。而动态存储分配方案则是在运行时刻根据...

    2019-2020第二学期C语言试卷及答案.zip

    9. **内存管理**:理解堆和栈的区别,学会使用malloc、calloc、realloc和free进行动态内存分配和释放。 10. **算法与数据结构**:C语言是学习算法和数据结构的良好工具,如排序算法(冒泡、选择、插入、快速等)、...

    第3章函数(1).pptx

    存储类型决定了变量的生命周期和内存分配方式,比如自动变量(栈上分配)、静态变量(全局或局部,持续整个程序或函数调用)和动态变量(堆上分配)。 编译预处理是C++的一个重要特性,它包括宏定义、条件编译等,...

    C/c++面试一百题

    - 内存管理:了解动态内存分配(malloc, free)和栈与堆的区别。 2. **C++语言特性**: - 面向对象编程:理解类、对象、封装、继承、多态的基本概念。 - 构造函数与析构函数:掌握对象生命周期中的初始化和清理...

    c++语意研究 C++高级特性研究 反汇编

    - **内存分配**:了解如何在堆和栈上分配内存对于编写高效和安全的代码至关重要。栈上的变量在函数结束时自动释放,而堆上的内存需要手动释放。 - **类型转换**:C++提供了多种方式来进行类型转换,包括隐式转换和...

    多线程并发编程-同步与互斥-原⼦变量-并发和⽆锁 数据结构

    thd 指向的变量会被设置为新线程的线程编号 ID,attr 指向 pthread_attr_t 的指针,用于设置线程属性,start 是函数指针,指向线程开始执行的函数入口,arg 是传递给 start 函数的参数。 线程同步和互斥是多线程...

    java面试笔试总结

    - **方法**:理解方法的作用、参数传递机制以及重载和重写的概念。 - **类与对象**:掌握类的定义、对象的创建以及封装、继承和多态等面向对象特性。 - **异常处理**:理解try-catch-finally结构,以及如何自定义...

    经典编程900例(c语言)(1)

    2. **函数**:函数定义、调用、参数传递、递归函数。 3. **数组**:一维、二维数组的使用,动态内存分配。 4. **指针**:指针的基本操作,指针与数组、函数的关系,指针在内存管理中的应用。 5. **结构体与联合体**...

    Java上海汉得笔试题+答案解析

    - **选项 B 正确:**从内存回收的角度看,Java 堆中可以细分为新生代和老年代。 **结论:** 正确选项为 C: 所有的对象实例以及数组都要在堆上分配;从内存回收的角度看,Java 堆中可以细分为新生代和老年代。

    嵌入式C笔试题大全

    - 静态存储区、栈区和堆区的区别,以及动态内存分配(malloc/free)的应用场景和注意事项。 3. **预处理指令**: - 宏定义(#define)、条件编译(#ifdef/#ifndef/#endif)、头文件包含(#include)等。 4. **...

    新概念C语言学习_word

    理解函数的定义、调用、参数传递和返回值是C语言学习的关键。 4. **指针**:C语言的指针是其强大之处,它们可以用来直接操作内存,实现高效的数据操作。理解指针的概念、操作及指针与数组、函数的关系,是掌握C语言...

    C语言深度解剖

    - 内存管理是C语言中一个重要的主题,包括栈内存和堆内存的区别、动态内存分配函数如`malloc`和`free`的使用等。 - 通过对数组和内存管理的实际案例分析,帮助学习者理解如何有效地管理和利用内存资源。 3. **...

    高级C语言 学完C语言来看这个绝对收获

    - **函数指针**:理解和使用函数指针,它可以作为参数传递给其他函数。 - **位域**:使用位域节省空间,但要注意不同编译器的实现差异。 #### 9. C语言中实现数组的动态增长 使用realloc()函数动态调整数组大小,...

    关于JS变量和作用域详解

    从对象的角度来看,当函数的参数是一个对象时,参数对象和外部对象引用同一个对象。然而,外部对象指向的对象在堆内存中只有一个,且通常是全局变量。不要错误地认为在局部作用域中修改的对象会在全局作用域中反映...

Global site tag (gtag.js) - Google Analytics