theme: cyanosis
引用数据类型的本质
引用数据类型变量存储的是对象的引用(内存地址),而非对象本身。
想象一下:如果对象是一栋房子,那么引用就是这栋房子的地址。当你写:
Person p1 = new Person("张三", 25);
这里发生了两件事:
- 在堆内存中创建了一个
Person
对象 p1
变量存储了这个对象的"地址"(引用)
当进行赋值操作时:
Person p2 = p1;
我们只是复制了地址,而不是复制了房子。现在p1
和p2
都指向同一栋"房子"(同一个对象)。
Java中的引用类型家族
Java中的所有引用类型都遵循这一原则:
- 类(Class):
String
、自定义类等 - 接口(Interface):
List
、Map
等 - 数组(Array): 即使是基本类型数组,数组本身仍是引用类型
- 枚举(Enum): 本质上是特殊的类
引用比较与内容比较
理解引用的本质,可以解释很多Java编程中的"谜题":
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2); // true,同一个字符串池中的对象
System.out.println(s1 == s3); // false,不同的对象引用
System.out.println(s1.equals(s3)); // true,内容相同
这就像两张纸上写着相同的地址——地址相同(==
为true),或两张纸上写着不同地址但指向外观完全相同的房子(equals()
为true)。
包装类的缓存机制
Java的设计者为提高性能,对常用的小数值包装类对象进行了缓存:
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true,使用了同一个缓存对象
Integer c = 1000;
Integer d = 1000;
System.out.println(c == d); // false,超出缓存范围,创建了不同对象
这就像在一个小区里,1-127号房子是公司统一建好的标准户型(缓存),而更大号码的房子则是按需定制建造的。
总结
- Java中,引用类型变量是对象的"遥控器",而不是对象本身
- 所有非基本类型的变量都是引用
- 引用的行为解释了
==
和equals()
的区别 - 包装类的缓存机制是性能优化的结果
理解引用的本质,能够避免许多常见错误,尤其是在处理对象相等性、参数传递和集合操作时。引用是Java内存模型的基础,掌握它将使你的编程之路更加顺畅。