在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中参数的传递是值传递,形参和实参占用了不同的内存空间,只是在传递基本类型和对象时这个“值”的含义不同而已。
分享到:
相关推荐
第一,从软件设计的角度看,栈代表了处理规律,而堆代表了数据。这样分开,使得处理规律更为清楚。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。其次,堆与栈的分别,使得堆中的内容可以被...
第一,从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰。分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。第二,堆与栈的分离,使得堆中的内容可以被...
尽管ActivityGroup已经被淘汰,但我们仍然可以从历史的角度来理解它的运作机制和一些关键知识点。 1. **ActivityGroup的生命周期**: - ActivityGroup内部管理的子Activity并不直接遵循正常的Activity生命周期。当...
本书深入剖析了内存区域划分,包括栈区、堆区、静态区和代码区等,并解释了每个区域的特点及应用场景。此外,书中还详细探讨了C/C++中的指针概念,包括指针的基本操作、指针与数组的关系、指针与函数等,帮助读者...
其次,从存储分配的角度来看,主要有静态存储分配和动态存储分配两种方案。静态存储分配的方案是在编译阶段为所有的数据对象分配固定的存储空间,运行时刻存储单元大小不变。而动态存储分配方案则是在运行时刻根据...
9. **内存管理**:理解堆和栈的区别,学会使用malloc、calloc、realloc和free进行动态内存分配和释放。 10. **算法与数据结构**:C语言是学习算法和数据结构的良好工具,如排序算法(冒泡、选择、插入、快速等)、...
存储类型决定了变量的生命周期和内存分配方式,比如自动变量(栈上分配)、静态变量(全局或局部,持续整个程序或函数调用)和动态变量(堆上分配)。 编译预处理是C++的一个重要特性,它包括宏定义、条件编译等,...
- 内存管理:了解动态内存分配(malloc, free)和栈与堆的区别。 2. **C++语言特性**: - 面向对象编程:理解类、对象、封装、继承、多态的基本概念。 - 构造函数与析构函数:掌握对象生命周期中的初始化和清理...
thd 指向的变量会被设置为新线程的线程编号 ID,attr 指向 pthread_attr_t 的指针,用于设置线程属性,start 是函数指针,指向线程开始执行的函数入口,arg 是传递给 start 函数的参数。 线程同步和互斥是多线程...
- **方法**:理解方法的作用、参数传递机制以及重载和重写的概念。 - **类与对象**:掌握类的定义、对象的创建以及封装、继承和多态等面向对象特性。 - **异常处理**:理解try-catch-finally结构,以及如何自定义...
2. **函数**:函数定义、调用、参数传递、递归函数。 3. **数组**:一维、二维数组的使用,动态内存分配。 4. **指针**:指针的基本操作,指针与数组、函数的关系,指针在内存管理中的应用。 5. **结构体与联合体**...
- **选项 B 正确:**从内存回收的角度看,Java 堆中可以细分为新生代和老年代。 **结论:** 正确选项为 C: 所有的对象实例以及数组都要在堆上分配;从内存回收的角度看,Java 堆中可以细分为新生代和老年代。
- 静态存储区、栈区和堆区的区别,以及动态内存分配(malloc/free)的应用场景和注意事项。 3. **预处理指令**: - 宏定义(#define)、条件编译(#ifdef/#ifndef/#endif)、头文件包含(#include)等。 4. **...
理解函数的定义、调用、参数传递和返回值是C语言学习的关键。 4. **指针**:C语言的指针是其强大之处,它们可以用来直接操作内存,实现高效的数据操作。理解指针的概念、操作及指针与数组、函数的关系,是掌握C语言...
- **函数指针**:理解和使用函数指针,它可以作为参数传递给其他函数。 - **位域**:使用位域节省空间,但要注意不同编译器的实现差异。 #### 9. C语言中实现数组的动态增长 使用realloc()函数动态调整数组大小,...
从对象的角度来看,当函数的参数是一个对象时,参数对象和外部对象引用同一个对象。然而,外部对象指向的对象在堆内存中只有一个,且通常是全局变量。不要错误地认为在局部作用域中修改的对象会在全局作用域中反映...