- 作者:老汪软件技巧
- 发表时间:2024-09-27 21:02
- 浏览量:
大家好,这里是小奏,觉得文章不错可以关注公众号小奏技术
java基本类型
在 Java 中,基本数据类型(如 int, float, boolean 等)是值传递
public class ValuePassExample {
public static void main(String[] args) {
int x = 10;
changeValue(x);
System.out.println(x); // 输出 10,x 的值没有改变
}
static void changeValue(int num) {
num = 20;
}
}
引用类型(对象)
在 Java 中,引用类型是引用传递,我们来看看几个例子
jdk提供的对象
public class ReferencePassExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
changeValue(sb);
System.out.println(sb); // 输出 "Hello XiaoZou",sb 被修改了
}
static void changeValue(StringBuilder s) {
s.append(" XiaoZou");
}
}
这里可以看到通过改变引用对象的值,原始对象也被改变了
自定义对象
class Student {
String name;
Student(String name) {
this.name = name;
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("xiaozou");
// 情况 1: 修改对象的字段
updateName(s);
System.out.println(s.name); // 输出 java
// 情况 2: 尝试重新赋值对象
updateStudent(s);
System.out.println(s.name); // java
}
public static void updateName(Student student) {
student.name = "java"; // 修改成功
}
public static void updateStudent(Student student) {
student = new Student("xiaozou"); // 不会影响原对象
}
}
这里分两种情况
我们通过引用修改对象的字段,原始对象也被修改了我们尝试重新赋值对象,但是原始对象并没有被改变
为什么会这样呢?我们简单通过图片理解一下
首先在main方法中 我们创建了一个s对象,s指向了一个Student对象
然后我们调用updateName方法,s的引用被复制并传递给方法,但是main方法中的s还是指向原来的Student对象
然后我们通过修改引用的Student实际对象的值,外面的Student对象也会发生变化
因为现在我们指向的是同一个Student对象
然后我们调用updateStudent方法,s的引用被复制并传递给方法,但是我们在方法中将s的引用修改为指向新的Student对象,但是main方法中的s还是指向原来的Student对象
所以即使修改了引用的Student对象,外面的Student对象并不会发生变化
GO
Go 语言只有值传递,但是可以通过指针来模拟引用传递的效果
值传递
package main
import "fmt"
func main() {
x := 10
changeValue(x)
fmt.Println(x) // 输出 10
}
func changeValue(num int) {
num = 20
}
使用指针模拟引用传递
package main
import "fmt"
type Student struct {
Name string
}
func main() {
s := Student{Name: "Alice"}
// 情况 1: 传递指针,修改结构体字段
updateName(&s)
fmt.Println(s.Name) // 输出 "Bob"
// 情况 2: 传递指针,尝试重新赋值
updateStudent(&s)
fmt.Println(s.Name) // 输出 "Charlie"
}
func updateName(student *Student) {
student.Name = "Bob" // 修改成功
}
func updateStudent(student *Student) {
*student = Student{Name: "Charlie"} // 修改成功
}
在 Go 中,如果你想在函数内部修改传入的对象,你需要传递该对象的指针。通过指针,你可以修改对象的字段,甚至可以完全替换该对象。
总结
在Java中弱化了指针的概念,已经没有指针了。所以有时候我们进行一些对象的update操作会感觉很奇怪
比如像上面的例子,明明都是修改s,一个影响到了原对象,一个却没有影响到原对象
实际我们要区分这两种情况,虽然都是复制了一个引用
golang中就不一样,如果你不定义指针,那么你就只能进行值传递,不管你如何修改,都改变不了原对象
想要修改原对象,你就必须需要传递指针,方法定义中的参数就必须是指针比如*Student