值传递和引用传递、对象类型与基本类型、实参与形参之间、栈堆之间的七七八八

数据和变量的分类

首先,我们需要大概明白,java中的数据类型分为两类,基本类型对象类型(一些特殊的如String后续讨论)

基本类型:byte,short,int,long,char,float,double,boolean,returnAddress
对象类型:类类型,接口类型和数组

以上数据类型是针对数据本身特点而言的,如果我们要使用他们,也就是数据成为了变量,此时结合数据在内存中的保存方式,对应的叫法成为了基本类型引用类型
基本类型保存的是对象本身的值,而引用类型保存的是引用的值,也就是对象地址的值。

数据是怎么存的

数据是怎么存的,其实是个很复杂的话题,需要涉及到很多java内存模型的知识,此处不再深入拓展。从以下场景的代码来简单说明下

// 首先需要明白,People这个对象实例化就是放在堆中的,所以它里面的成员变量自然也是在堆中的。
Class People{
	// age是一个基本类型
	int age;
	// child是一个引用类型
	People child;
	void setAge(int age){
		this.age = age;
	}
	void setChild(int child){
		this.child= child;
	}
}
Class People Test(){
	public void createPeople(){
		// 这一步只是声明了一个引用类型的变量man,并为他在方法栈中分配了内存空间,用来存放之后对象的地址值
		People man;
		// 这一步在内存中创建了一个对象,并将对象的地址值(比如A0X456465之类的)赋值给了man这个引用变量 
		man = new People()
		// 这一步是在方法栈中声明了一个基本类型的变量age,并为他分配了内存用来存储数据本身。
		int age;
		// 这里的10是存在方法栈中的。
		age = 10;
		// 这里将方法区中定义并赋值的基本变量age的值赋值给了引用变量man所指向的对象的成员变量age。所以man.age的值是存在堆中的。
		man.setAge(age);
		// 这里将一个堆中对象child的地址值赋值给了man中的引用成员变量child。所以其实man.child与方法中定义的child这两个引用变量,指向的是同一个堆中的对象所在的地址
		People child = new People;
		man.setChild(child);
		
	}
}

实参与形参

// 这里的age是实参
int age = 10;
// 方法签名里的就是形参
setAge(age);

引用传递和值传递

值传递

值传递就是实参把它的值传给形参,基本数据类型都是值传递,即函数接受的是实参的一个copy,内存中存在两份参数,也就是两份变量和值,方法中对参数的修改不会影响原本实参的值

引用传递

引用传递就是实参把引用传给形参,对象类型都是引用传递,即函数接受的是对象的地址值,内存中存在一份参数,一份变量和值,方法中对参数的修改会影响原本实参的值

结合存储方式做理解

其实造成这种区别的原因,结合上面数据的存储方式就很好理解了,不管是那种传递,传递本身的操作是一样的。
比如我定义了一个变量a,传递给方法test(),就是把这个变量a的值copy一份传给test()。
只不过当变量a的类型是基本数据类型的时候,a存储的就是值本身,传递的是一份原始值的copy,所以我们在方法中对传进来的a做修改,并不会影响到最初的a。
当变量a的类型是引用类型的时候,a存储的是引用本身,传的自然是引用的copy,我们在方法中对a做修改的时候,如果是对a指向的对象做修改(比如a.setAge(50)这种操作,这里假设age是一个成员变量),那么由于两个引用指向的是同一块堆中的内存,自然是有影响的。
如果是a = new A()这种操作,是不会影响到之前的a的,因为它没有对之前堆中对象做修改,只是改变了引用本身的值。

特殊情况

对于String、Integer、Double等几个基本类型包装类,都是immutable类型(为了深度拷贝方便),尽管他们是引用类型的变量,但是由于没有提供自身修改的函数,所以每次对对象的修改操作都会形成新的对象,即在堆中开辟新的内存,所以它的效果和值传递是一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

unhappy404

感谢老板打赏!!!爱您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值