java引用类型初步解析

引用类型的内存分配

在java中值分为两类,值类型与引用类型,值类型包括int、double、byte…等8个基本类型,而引用类型则是除基本类型以外的所有类型,包括class申请的自定义类。下面我们通过一张图来大概描述各种类型在内存中的存储形式。

在这里插入图片描述

由上图我们可以得出这样几个结论
所有的变量在进入内存都会顺序的存入栈中
在栈中基本类型的变量与数值是存在一起的而引用类型则新在堆中开辟了一片空间栈中存放的是空间地址。
字符串有两片存储值的空间地址

那么对引用变量赋值时是传值还是传引用呢?相信这是很多像我一样初学java的人经常会遇到的问题。
由此便引发了深拷贝浅拷贝问题,我们先来看一段代码
在这里插入图片描述
可以看到当A赋值给B时,并没有把值传递过去,而是将A开辟的地址传到了B,这便是浅拷贝传递引用。
在这里插入图片描述这时通过构造方法,把值传递到新的Student对象中,便实现了值的传递,也就是深拷贝。

了解了深浅拷贝之后,我们看下面代码,印证之前理论

		public static void main(String[] args){		
		T1 a = new T1();
		a.name = "王五";
		T1 b = new T1();
		b.name = "赵六";
		b = a;
		System.out.println(a.name);
		b.name = "快乐天使";
		System.out.println(a.name);
		}
		clsss T1{
			public String name;
			public int age;
		}

这段代码的运行结果如下:
在这里插入图片描述
可以看到最后的输出是“王五”,跟之前图片描述相符。b最后与a指向的是一片内存空间,所以b更改内容后a也收到影响。

引用类型的实质

通过上面的例子不难看出,提及引用必然离不开内存与地址,引用的类型的实质便是对内存地址的引用,通过地址访问内存,前面的b=a就是将地址赋值,值类型便是真值赋值,“=”的作用本质相同。

下面我们在看一段代码进一步加深对引用内存构成的理解。

		T1 a = new T1();
		a.name = "王五";
		T1 b = new T1();
		b.name = "赵六";
		tem(a,b);
		System.out.println(a.name + " " + b.name);
		tem1(a,b);
		System.out.println(a.name + " " + b.name);
		
	}
	public static void tem(T1 a,T1 b) {
		T1 temp = a;
		a = b;
		b = temp;
	}
	public static void tem1(T1 a,T1 b) {
		String temp = a.name;
		a.name = b.name;
		b.name = temp;
	}

运行结果如下图
在这里插入图片描述
可以看到在执行第一个函数后值没有发生改变,执行第二个函数后值发生了改变。
知识点:形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。当实参传入时,分配新的内存给形参后复制实参的值/地址,效果类似“=”)

第一个函数执行时完全是两个临时变量在换来换去,与实参没有任何关系。通过下图形象理解。
在这里插入图片描述那么第二个函数为什么能互换值呢?这便涉及了引用类型内部的结构。所有引用类型都是由基本类型构成实例对象其实就是分配空间后,调用构造函数赋初始值,把地址回传给栈中对应位置。那么这个空间分配多大,一开始程序是不能预知的,所以其实引用空间内存中存的也是地址。
(PS:一开始为引用分配的内存是固定的,若地址的内存总和小于分配内存,便会为引用分配若干基本类型地址,若大于分配内存,便会开辟一块更大的空间用来储存地址)
在这里插入图片描述
此片介绍了引用类型的基本构成以及地址指向,若有不明之处欢迎探讨。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值