果然知识网的发散是无止境的!
有关堆栈的相关知识在 迷途指针 中有所提及。
Java中除了基本数据类型,其他的均是引用类型,包括类、数组等等。
先看一下这两个变量的区别
void test1(){
int cnt = 0;
String str = new String("melo");
}
复制代码
比如我们创建了一个 Student student = new Student("Melo");
void test1(){
int cnt = 0;
cnt=1;
String str = new String("melo");
str="Melo";
}
复制代码
对于基本类型 cnt,赋值运算符会直接改变变量的值,原来的值直接被覆盖掉了。
ta无依无靠,不像下边一样有房子可以住。
对于引用类型 str,赋值运算符只会改变引用中所保存的地址,虽然原来的地址被覆盖掉了,str指向了一个新的对象,但是原来的那个老对象没有发生变化,他还是老老实实待在原来的地方!!!
有学过c语言的同学应该很清楚,这里借助c语言中的“指针”打个比喻。
当然,原来那个房子没有旗子插着了,没有人住了。也不能总是放任ta在那占着空间,过段时间也许就会有人来把他给拆了回收了(JVM)。 这种没有地方引用到的对象就称为垃圾对象。
我们上次聊到lambda的时候,提及到了值传递,那里的拷贝副本,就是我们这里要说的值传递
我们只是将实参传递给了方法的形参,将cnt值复制一份,赋值给形参val所以,函数内对形参的操作完全不会影响到实参真正存活的区域!而伴随着函数调用的结束,形参区域和其内的局部变量也会被释放。(方法栈的回收)
//基本类型的值传递
void unChange(int val) {
val = 100;
}
unChange(cnt); // cnt 并没有被改变
复制代码
实参传递给形参时,形参其实用的就是实参本身(而不再单纯只是拷贝一份副本出来了),当该形参变量被修改时,实参变量也会同步修改。
//内卷
void involution(Student temp){
temp.setScore(100);
}
public static void main(String[] args) {
Student student = new Student();
student.setName("Melo");
student.setScore(0);
System.out.println("躺平时的成绩->"+student.getScore());
new TestQuote().involution(student);
System.out.println("卷了几天后的成绩->"+student.getScore());
}
复制代码
看下边这段"反内卷"的代码实例
//反内卷
void againInvolution(Student temp){
temp = new Student();
temp.setScore(100);
}
public static void main(String[] args) {
Student student = new Student();
student.setName("Melo");
student.setScore(0);
System.out.println("企图内卷前的成绩->"+student.getScore());
new TestQuote().againInvolution(student);
System.out.println("遭受反内卷后的成绩->"+student.getScore());
}
复制代码
先给出答案吧,Java里边其实只有值传递!!!
其实我们这里的形参temp,只是拷贝了一份student的地址。可以理解为temp拷贝了这条指针,他也指向了student所指向的对象。
所以才会"反内卷"失败,跳出函数的时候,student所指向的对象成绩根本没有增长!!!
注意指针传递跟引用传递是不一样的
#include <stdio.h>
void swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main() {
int a = 5;
int b = 8;
//需要传递地址
swap(&a, &b);
printf("a = %d\n", a);
printf("b = %d", b);
}
复制代码
#include <iostream>
using namespace std;
int main()
{
//&标识符
void swap(int& x,int& y);
int a = 5;
int b = 8;
swap(a,b);
return 0;
}
void swap(int& a,int& b){
int temp;
temp = a;
a = b;
b = temp;
}
复制代码
如果该语言没有&,@这种取地址的操作符,一般来说就只有值传递的。如js和java。
经评论区小伙伴补充,不用&,@这种取地址的操作符也可以引用传递,参考C#的ref、out和in关键字。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。