Java基础07 String以及基础类型的封装类是值传递的哪一种形式
经过上一篇的博客(没看我上一篇博客的可以点击链接先去了解下Java是值传递还是引用传递),我们了解到Java中只有值传递,没有引用传递;我们也知道基础类型的数据传递是普通的值传递,引用类型(object对象)的数据一般是特殊的值传递(求值策略为共享对象传递
),还有一种引用类型(String 和基础数据的封装类)是普通的值传递还是特殊的值传递呢?我们来一起探究下。
来探究之前,我们先来看看引用类型为对象的数据传递情况:
public class Transmit {
public static void main(String[] args) {
Student student = new Student("小明", 23);
change(student);
System.out.println("学生的年龄:" + student.getAge());
}
private static void change(Student student1){
student1.setAge(80);
}
@Data
@AllArgsConstructor
static class Student{
private String name;
private int age;
}
}
打印输出结果:
学生的年龄:80
这个例子也是在上一篇博客举的,现在我们来分析下它的执行过程所做的一些操作。
- JVM在堆中开辟一块内存用于存储 Student 对象,对象包含 name、age两个属性。
- JVM在栈中分配一块内存给student,用于存储指向 Student 对象 的堆地址。
- JVM在复制一份student给student1,分配到栈内存中(student与student栈内存地址不同,但存储着相同的堆内存地址)。
- 将student1传入方法体中,改变age的值。
- 方法结束,打印student对象的age值,由于在方法中值改变了对象里面的属性值,没有改变student1的指向堆内存的地址,所以直接影响到student的数据。
我们再来看看String以及基础类的封装类的情况
public class Transmit {
public static void main(String[] args) {
String str = "hello";
changeStringValue(str);
System.out.println("字符串的值:" + str);
}
private static void changeStringValue(String str1){
str1 = "good";
}
}
打印输出结果:
字符串的值:hello
看到这个结果会不会感到惊讶,String 明明是引用类型,为什么经过changeStringValue方法不会改变原来的值。我们带着疑惑继续深究下去。
- JVM在堆中开辟一块内存用于存储 "hello"。
- JVM在栈中分配一块内存给str,用于存储指向 "hello" 的堆地址。
- JVM在复制一份str给str1,分配到栈内存中(str与str1栈内存地址不同,但存储着相同的堆内存地址)。
- 将str1传入方法体中。
- 方法体在堆内存中开辟一块内存,用于存储 "good"。
将str1的值改变,让其指向存储 "good" 的堆内存地址
。- 方法结束,打印str的值,这是由于str与str1指向堆内存不同,所以输出的还是 "hello"。
基本数据类型的封装类与 String 一样,我们只来看下例子的演示效果
public class Transmit {
public static void main(String[] args) {
Integer num = 1;
changeIntegerValue(num);
System.out.println("Integer的值:" + num);
}
private static void changeIntegerValue(Integer num){
num = 10;
}
}
打印输出结果:
Integer的值:1
看到这里,我相信大部分人应该能理解到其中缘由,至于还没有理解到的,可以多思考思考下,对于JVM方面不太了解的看客,可以先去了解下JVM的相关知识,我在后期也会写JVM系列知识博客,之后再加进来,JVM知识点有点多,我也不在这叙述了。
欢迎大家来关注我,让我们一起成长O(∩_∩)O哈哈~