四类八种基本类型
Java中一共有四类八种基本数据类型,看下表:
除掉这四类八种基本类型,其它的都是对象,也就是引用类型,包括数组。
代码示例
public class Test2 {
public static void main(String[] args) {
int int1 = 100;
int int2 = int1;
int1 = 500;
System.out.println(int1);
System.out.println(int2);
int[] arr1 = new int[]{1,2,3,4,5};
int[] arr2 = arr1;
arr2[3] = 8;
System.out.println(arr1[3]);
System.out.println(arr2[3]);
Person per1 = new Person("张三",21);
Person per2 = per1;
per2.setName("李四");
per2.setAge(35);
System.out.println(per1);
System.out.println(per2);
}
}
@Data
@AllArgsConstructor
class Person{
private String name;
private int age;
}
内存分析
基本类型
先看第一句代码:
int int1 = 100;
方法体里声明的基本数据类型在栈内存里,我们画一下
继续执行以下代码
int int2 = int1;
int1=500,直接修改int1的值为500,表现如下图
最终输出
500
100
数组
int[] arr1 = new int[]{1,2,3,4,5};
先初始化arr1,当执行到new这个关键字,会在堆内存分配内存空间,并把该内存空间的地址赋值给arr1。
继续执行以下代码
int[] arr2 = arr1;
这儿arr2初始化时并没有new关键字,并不会在堆内存里新开辟一块空间,而是把arr1里存的堆内存地址直接赋值给了arr2,对于引用类型来说,赋值(=号)就相当于拷贝了一份内存地址,也就是说arr1,arr2现在指向了同一块堆内存,表现形势如下图
这时候执行如下代码
arr2[3] = 8;
虽然只是修改arr1数组下标位置为3的值
但由于数组arr1和数组arr2指向同一块堆内存,打印arr1[3]和arr2[3]的值,都是8。
8
8
对象
再来看对象的初始化
Person per1 = new Person("张三",21);
当看到这个new,这货肯定在堆内存里开辟了一块内存空间,Person里有一个叫name的String对象,String这个对象有点特殊,虽然没有new这个关键字,但还是在堆内存中开辟了一块空间,在String是一个很普通的类一文中已经讲解过了,这里就不再细讲了,String底层是数组实现的,数组也是引用类型,age为基本数据类型,表现如下图
上图中大框里的内容就是整个Person对象在堆内存中的体现,继续执行以下代码
Person per2 = per1;
没有new关键字,per2不会在堆内存中新开辟空间,和数组一样,也是把per1的内存地址直接赋值给了per2。
当我们修改per1的属性的时候
per2.setName("李四");
per2.setAge(35);
如下图两个红框里的内容,给对象(数组也是对象)赋值其实就是相当于引用重新指向一块堆内存,基本数据类型是直接修改值,表现如下图
所以,不管打印per1还是per2的name、age,打印出来的结果都是“李四”、35。
输出
Person(name=李四, age=35)
Person(name=李四, age=35)