印象中记得 java 的参数传递方式是引用传递,但是为什么对于基本类型在函数里的参数修改不会影响到函数外传入的变量呢,是因为对于基本类型来说,值就存储在变量本身了吗,还是说基本类型的值是存在栈上,只不过随着函数调用,参数压栈后,对应的值也会跟着参数复制一份,对参数本身的修改就不会影响到函数外传入的值,而对象参数是指向堆的一个地址,即使复制了,也是同一个地址,因此在函数内修改参数对象的值会影响函数外传入的对象值。
如果想要让 java 也能做到类似 C 语言的解引用,类似 int* aAddr = &b
,是不是只要让栈地址暴露出去就可以了。
public class Reference {
public static void main(String[] args) {
Reference reference = new Reference();
Student student = new Student(1);
System.out.printf("before change student's age: %d\n", student.age);
reference.changeReference(student);
System.out.printf("after change student's age: %d\n", student.age);
int a = 1;
System.out.printf("before change int: %d\n", a);
reference.changePrimitive(a);
System.out.printf("after change int: %d\n", a);
}
void changeReference(Student s) {
s.age += 1;
}
void changePrimitive(int a) {
a = 2;
}
static class Student {
int age;
public Student(int age) {
this.age = age;
}
}
}
1
Jooooooooo 2022-10-30 18:35:39 +08:00
java 是值传递, 对象传的是指针.
基本类型在 java 里确实特殊, 和对象不是一回事 |
2
857681664 OP 正文里说错了,应该是值传递,刚才又想到,对于基本类型和对象的 print 也会显示不一样的行为,基本类型打印值,对象打印的是堆地址,是不是 java 的基本类型没有地址这一说法,还是 jvm 把基本类型的地址隐藏起来了。
|
3
cpstar 2022-10-30 20:15:04 +08:00
可以理解基本类型在 java 中是异类,所有就解释通了。为什么要用异类的 int 而不用对象 Integer ,想通了?
至于输出和使用等等,如果你了解 JVM 的原理,那就根本不会存在到底是引用还是值这个概念,存入的都是值,只不过指令类型不一样。比如 int 的 add 会翻译成 iadd ,然后后边的两个操作数直接相加,而 Integer 的 add 则会一系列 aload 和 invokevirtual 。 换句话,如果在 bytecode 层面,把 iadd 换成了 invokevirtual ,那就会可能产生你说的 int* aAddr = &b 效果,比如我曾经在 bytecode 层面做出 boolean t; if (t>=0)这样的操作。 |
4
snailsir 2022-10-31 09:33:37 +08:00
|
5
snailsir 2022-10-31 09:36:42 +08:00
或者看微信公众号发的也行: https://mp.weixin.qq.com/s/h8JW3H1KMS9DXFgGYiwJJg
|