四类八种基本类型

Java中一共有四类八种基本数据类型,看下表:
基本类型和引用类型 - 图1
除掉这四类八种基本类型,其它的都是对象,也就是引用类型,包括数组。

代码示例

  1. public class Test2 {
  2. public static void main(String[] args) {
  3. int int1 = 100;
  4. int int2 = int1;
  5. int1 = 500;
  6. System.out.println(int1);
  7. System.out.println(int2);
  8. int[] arr1 = new int[]{1,2,3,4,5};
  9. int[] arr2 = arr1;
  10. arr2[3] = 8;
  11. System.out.println(arr1[3]);
  12. System.out.println(arr2[3]);
  13. Person per1 = new Person("张三",21);
  14. Person per2 = per1;
  15. per2.setName("李四");
  16. per2.setAge(35);
  17. System.out.println(per1);
  18. System.out.println(per2);
  19. }
  20. }
  21. @Data
  22. @AllArgsConstructor
  23. class Person{
  24. private String name;
  25. private int age;
  26. }

内存分析

基本类型

先看第一句代码:

  1. int int1 = 100;

方法体里声明的基本数据类型在栈内存里,我们画一下
基本类型和引用类型 - 图2
继续执行以下代码

  1. int int2 = int1;

基本类型和引用类型 - 图3
int1=500,直接修改int1的值为500,表现如下图
基本类型和引用类型 - 图4
最终输出

  1. 500
  2. 100

数组

  1. int[] arr1 = new int[]{1,2,3,4,5};

基本类型和引用类型 - 图5
先初始化arr1,当执行到new这个关键字,会在堆内存分配内存空间,并把该内存空间的地址赋值给arr1。
继续执行以下代码

  1. int[] arr2 = arr1;

这儿arr2初始化时并没有new关键字,并不会在堆内存里新开辟一块空间,而是把arr1里存的堆内存地址直接赋值给了arr2,对于引用类型来说赋值(=号)就相当于拷贝了一份内存地址,也就是说arr1,arr2现在指向了同一块堆内存,表现形势如下图
基本类型和引用类型 - 图6
这时候执行如下代码

  1. arr2[3] = 8;

虽然只是修改arr1数组下标位置为3的值
基本类型和引用类型 - 图7
但由于数组arr1和数组arr2指向同一块堆内存,打印arr1[3]和arr2[3]的值,都是8。

  1. 8
  2. 8

对象

再来看对象的初始化

  1. Person per1 = new Person("张三",21);

当看到这个new,这货肯定在堆内存里开辟了一块内存空间,Person里有一个叫name的String对象,String这个对象有点特殊,虽然没有new这个关键字,但还是在堆内存中开辟了一块空间,在String是一个很普通的类一文中已经讲解过了,这里就不再细讲了,String底层是数组实现的,数组也是引用类型,age为基本数据类型,表现如下图
基本类型和引用类型 - 图8
上图中大框里的内容就是整个Person对象在堆内存中的体现,继续执行以下代码

  1. Person per2 = per1;

没有new关键字,per2不会在堆内存中新开辟空间,和数组一样,也是把per1的内存地址直接赋值给了per2。
基本类型和引用类型 - 图9
当我们修改per1的属性的时候

  1. per2.setName("李四");
  2. per2.setAge(35);

如下图两个红框里的内容,给对象(数组也是对象)赋值其实就是相当于引用重新指向一块堆内存,基本数据类型是直接修改值,表现如下图
基本类型和引用类型 - 图10
所以,不管打印per1还是per2的name、age,打印出来的结果都是“李四”、35。
输出

  1. Person(name=李四, age=35)
  2. Person(name=李四, age=35)