小白第一步|Java传值传引用基础知识小结

前言:

传值传引用的重要性想必不需要我再多说了,这是编程语言的重难点和基础,有了它之后才能更顺利的进行下面的工作;

下面我们开始介绍Java的传值传引用的相关知识

首先我们需要了解两个概念:栈和堆

栈和堆区别于数据结构中的栈和堆,这里的栈和堆是我们程序内存的放置区域
其中
栈区(stack): 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,申请方式为直接进行变量的声明即可,编译器自动将相关的变量和参数放到栈中
堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,申请方式是由程序员显式申请
例如:
(test*)malloc(sizeof(test))
或者
new Student();
又或者创建数组
这几句都会显式的为一个变量创建内存区域。

下面我们就来正式对传值和传引用的概念进行分析:

首先声明:传引用等于将引用的地址传到函数或参数中,所以本质上Java只存在值传递!

首先看以下程序:

package temp;

public class temp {
	 public static void changeData(int data){
	        data = 80;
	    }
	 public static void main(String[] args) {
	        int a = 10;
	        System.out.println(a);
	        changeData(a);
	        System.out.println(a);
	    }
}

输出的结果是什么呢?
跑一个!
在这里插入图片描述在这里插入图片描述

为什么是两个10呢?

首先,声明为int类型的变量a是一个局部变量,储存在我们的栈中
在这里插入图片描述
传到函数中之后,其再创建了一个叫data的int类型局部变量,并赋值为10
在这里插入图片描述
我们再改变data的值
发现了吗?
其对变量a的值毫无影响
在这里插入图片描述
因此在主函数中,两次的输出都是10
这就是我们比较常见的传值

再看以下含对象创建和数组函数的程序

package temp;

public class temp {
	 public int age;
	 temp(){
		 age = 10;
	 }
	 //数组变值
	 public static void changeData(int []data){
	        data[0] = 80;
	    }
	 //对象属性变值
	 public static void change(temp tu){
		 tu.age = 80;
	 }
	 public static void main(String[] args) {
	        int []a = {10,50};
	        System.out.println(a[0]);
	        changeData(a);
	        System.out.println(a[0]);
	        
	        System.out.println();
	        temp t = new temp();
	        System.out.println(t.age);
	        change(t);
	        System.out.println(t.age);
	    }
}

输出的结果是什么呢?
同样跑一个!
在这里插入图片描述
这次你可能会问了:
为什么不是都是10了???????
xxx为什么??????(理解成一句俗语)
这时候,我们的堆同学就派上了用场!在这里插入图片描述
首先是数组:我们创建数组是存在我们的堆内
而数组名a其实是数组的首地址,也就是在栈中创建了一个保存了数组地址的一个变量
在这里插入图片描述
使用changeData函数后,传参语句中创建了一个同样保存这个数组地址的一个变量,存在我们的栈中
在这里插入图片描述
由于a和data指向的是同一数组,我们在函数中更改了data指向的数组的元素值,也就是更改了a指向的元素的值,
在这里插入图片描述
因此我们在函数中改变了数组元素值,同样在函数外也会改变
同样的原理,在创建对象时,我们对其的解释是这样的:
temp t = new temp();
相当于先a = new temp(),调用构造函数创建一个temp类的对象,给予堆的内存空间,a保存的是这个对象的位置信息
在这里插入图片描述
再temp t = a,将a所存的地址信息赋给创建在栈中的temp类型的变量t(也叫将对象的引用传给t)在这里插入图片描述
然后在change函数的传参中创建一个temp类型的变量tu,赋给的同样是位置信息
在这里插入图片描述
这样的话,修改tu所指的age属性也就是修改t所指的位置信息
因此主函数中的t.age被改变

这就是为什么对象和数组的值会改变的原因
下面还有一个议题:
在Java中还有一些比较特殊的类,如库内的String类等;
看以下的程序

package temp;

public class temp {
	public static void change(String temp){
		temp = "list2";
	}
	public static void main(String[] args) {
        String s=new String("list1");
        System.out.println(s);
        change(s);
        System.out.println(s);
	}
}

猜一猜结果?
list1
list2
按照第二个理论应该是这样的啊
但是,
咱们跑一下!
在这里插入图片描述

你!骗!我!

在这里插入图片描述
“不不不,怎么会骗人嘛!”
其实原因是:像String这样的比较特殊的类声明的时候就是final修饰不可变了
而在主函数创建String类型对象,在change函数中由于final的不可变性,也会隐式地在内存中开辟一块新空间(应该是没有改变存储的区域)
因此,在主函数的s和在change函数中的temp其实指向的是两个内存空间
这样修改一个,另外一个当然就不会被修改咯!

因此结果是两个list1

以上就是有关Java传值传引用的一些基本知识

本期over!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值