Java 引用数据类型详细讲解

一、核心概念

  1. 分类:除8种基本类型外,其余全是引用数据类型;
  2. 存储原理:
    • 基本类型变量:栈中直接存真实数值
    • 引用类型变量:栈中存对象在堆中的内存地址,通过地址找到堆里的实体数据。
  3. 默认初始值:null(代表没有指向任何对象)。
  4. 共性:都继承自 java.lang.Object,拥有 Object 通用方法:toString()equals()hashCode() 等。

二、四大类引用数据类型

1. 类(Class)

自定义类、系统内置类都属于引用类型。

// Person是自定义类,p为引用变量
Person p = new Person();
  • new Person():在堆内存创建对象;
  • p:栈内存保存对象地址,指向堆对象。

2. 接口(Interface)

接口本身不能new,只能由实现类对象接收引用。

interface Play {}
class Game implements Play {}
// 多态写法,接口引用指向实现类对象
Play play = new Game();

3. 数组(Array)

数组不管存基本类型还是对象,数组本身都是引用类型。

// int是基本类型,但int[]数组是引用类型
int[] arr = new int[5];
String[] strArr = new String[3];

4. 字符串 String

特殊引用类型,底层字符数组,写法简化,双引号直接赋值。

String s1 = "abc";
String s2 = new String("abc");

三、内存图解逻辑(简化)

栈内存:变量名 → 地址值
堆内存:地址对应真实对象/数组数据

示例:

Student stu = new Student();
  1. 执行 new Student(),堆开辟空间,创建学生对象;
  2. 把对象内存地址赋值给栈中的 stu
  3. 使用 stu.属性 / stu.方法() 时,通过地址找到堆对象操作。

四、引用传递特点

引用传递传递的是地址,多个引用可以指向同一个堆对象,一个引用修改对象内容,其他引用同步可见。

class Student{
    int age;
}
public class Test{
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.age = 18;
        // s2和s1指向同一个对象
        Student s2 = s1;
        s2.age = 20;
        System.out.println(s1.age); // 输出20
    }
}

五、null 空引用

  1. null 表示引用变量不指向任何堆对象;
  2. 若用null调用方法/属性,抛出 NullPointerException 空指针异常;
String str = null;
str.length(); // 报错空指针

六、引用类型 vs 基本类型对比

对比项 基本数据类型 引用数据类型
存储内容 真实数值 对象内存地址
内存位置 栈内存 栈存地址,堆存实体
数量 固定8种 无限,可自定义类
默认值 0、0.0、false、‘\u0000’ null
参数传递 值传递(拷贝数值) 引用传递(拷贝地址)
是否继承Object 不继承 全部继承Object

七、常见子类举例

  1. 类:StringScannerArrayList、自定义实体类;
  2. 数组:int[]double[]String[]、自定义类数组;
  3. 接口:ListRunnableComparable
  4. 包装类特殊说明:IntegerDouble 属于引用类型,对应基本类型的包装。

更多推荐