Java:引用数据类型和传值数据类型

java相较于c/c++没有指针的概念,但是不同名称的变量共用同一内存地址在java中是存在的。
有必要介绍下不同对象赋值时,java中那些数据是作为引用,那些是作为传值。
引用数据类型
这是一个People类,只有性别一个数据成员
public class People {
int sex; //性别,0为男性,非0为女性
}
现在我们做一个这个自定义类做一个小实验。
//////////////////////////////////////////
//引用数据类型
//////////////////////////////////////////
// 1
//
People LiLei = new People();
LiLei.sex=0;
People hmm=LiLei;
// 2
//输出true
//修改前 韩梅梅和李雷内存地址相同
System.out.println(hmm==LiLei);
// 3
//修改韩梅梅性别为1
hmm.sex=1;
// 4
//输出仍旧为true
//修改后 韩梅梅和李雷内存地址仍旧相同
System.out.println(hmm==LiLei);
// 5
// 李雷成功变性为1,但是变性的操作是通过韩梅梅实现的,
// 说明韩梅梅的身份其实只是李雷的马甲,它们是同一个人
System.out.println(LiLei.sex);
实验中,我们对韩梅梅性别的变动会同时影响到李雷,而且用“==”符号判断的结果任何情况下都为true。
说明对于用户定义的类对象的相互赋值,传递的其实是内存地址,而不是其值,是引用行数据类型。
除此之外的引用型数据类型还有:
- 数组
- 集合
传值数据类型
现在我们换成java中的基本数据类型
//////////////////////////////////////////
//传值数据类型
//////////////////////////////////////////
//1. 对ppp_int对象初始值为5
int ppp_int = 5;
//2. 使用ppp_int对paz_int初始化
int paz_int = ppp_int;
//3. 输出结果为true!!!
System.out.println(paz_int == ppp_int);
//4. 现在修改paz_int对象
paz_int = 4;
//5. 输出结果变为false
System.out.println(paz_int == ppp_int);
//6. 输出结果为5,说明对paz_int的修改并没有影响到ppp_int
System.out.println(ppp_int);
这次我们发现,对paz_int的修改并不会造成ppp_int的变化,因此显然他们并不是共用同一内存地址。
int是传值型数据。
相信细心的朋友还能发现一点,就是操作【2】 int paz_int = ppp_int; 结束后,ppp_int和paz_int二者的内存地址其实是一样的,只是操作【4】执行后才发生了变化。我猜测这是出于对内存空间的节省做出的选择。因为如果如果不修改,paz_int的值和ppp_int的值其实是一致的,与其使用两份内存空间,不如放在同一内存空间中。
更多
上一篇文章的末尾处,我们发现对String对象的修改,会造成String对象内存空间的变化,与其说是修改倒不如说是建立新的对象,销毁久对象。
但是上次文章中是存在不严谨的地方,在此换个方法再验证下。
//1. 获得ppp_int对象的内存位置
int address_ppp_0 = System.identityHashCode(ppp_int);
//2. 再次获得ppp_int对象的内存位置
int address_ppp_1 = System.identityHashCode(ppp_int);
//3. 【修改ppp_int后】再获得获得ppp_int的内存位置
int address_ppp_2 = System.identityHashCode(++ppp_int);
//4. true 没有发生变化
System.out.println(address_ppp_0 == address_ppp_1);
//5. false 发生了变化
System.out.println(address_ppp_0 == address_ppp_2);
在这个案例中,我发现即使只是对同一对象的修改,也会造成这个对象内存地址的变化。
有没有感觉java语言的有趣😏