值传递
值传递的理解
值传递是指多个参数在栈中的值得传递,大致过程可以认为是将参数的值拷贝一份,让这个拷贝到得到的值来进行赋值或其他的运算。
值传递的实例
例1:
int a = 5;
int b = a; //将a的值拷贝一份赋给b
int a = 5;
int b = a + 1; //将a的值拷贝一份,对拷贝得到的进行运算,加一得到的值再赋给b;
例2:
public static void main(String[]argsStrings) {
int a=10;
change(a);
System.out.println(a);
a++;
}
public static void change(int temp) { //在change方法中开辟了新的内存空间,即temp
System.out.println(temp); //这个temp中的值与主方法中的a是两个独立的参数
temp++;
System.out.println(temp);
}
//最终输出结果: 10 11 10
引用传递
引用传递的理解
引用传递可以理解为是一种地址的传递,并没有开辟新的内存空间,而是将原有的内存空间的地址传递给其他参数,通过其他参数对值的修改来原有数的值。
引用传递的实例
例1:
对于下面例子中的tem1,tem2可以理解为引用类型的变量,其中存放的是实际对象的地址(一般这种变量为"引用",引用指向实际对象,实际对象保存着内容,而这种引用储存在栈中。<=>与这种变量不同的是基本类型的变量,基本类型的变量自身就保存着内容。)=>理解起来可以参考c++中指针变量。
public static void main(String[] args) {
Temp tem1 = new Temp();
Temp tem2 = new Temp(6);
Temp tem3 = new Temp(7);
tem1.seta(5);
System.out.println(tem1.a+" "+tem2.a+" "+tem3.a);
tem2 = tem1 ;
tem3 = tem2 ;
// Temp temp = new Temp(8);
// temp = tem2;
// tem2=tem1;
// tem3 = temp;
System.out.println(tem1.a+" "+tem2.a+" "+tem3.a);
}
//此时输出的是5 5 5=>因为 tem2 = tem1 的语句将tem1的首地址赋给了tem2 ;
// 而 tem3 = tem2 将tem2的首地址赋给tem2,此时的tem2的首地址已经更改为
// tem1的,因此tem1,tem2,tem3所访问的对象一样。
对上面代码的注解位置进行改变
package 参数传值;
public class 引用传递 {
public static void main(String[] args) {
Temp tem1 = new Temp();
Temp tem2 = new Temp(6);
Temp tem3 = new Temp(7);
tem1.seta(5);
System.out.println(tem1.a+" "+tem2.a+" "+tem3.a);
// tem2 = tem1 ;
// tem3 = tem2 ;
Temp temp = new Temp(8);
temp = tem2;
tem2=tem1;
tem3 = temp;
System.out.println(tem1.a+" "+tem2.a+" "+tem3.a);
}
}
//此时输出的是5 5 6 =>通过添加了一个temp来保存tem2 的地址,因此tem3最后访问的对象为tem2
对变量的整理
基本变量
byte
short
int
long
boolean
float
double
char
每种基本变量都有与其相对应的封装类(也称引用变量)
相对应的封装类:
Byte
Short
Interger
Long
Boolean
Float
Double
Character
引用类型
1、引用类型可以类比c++中的指针。
2、类(class)=>自己定义的类也可以、抽象类(abstract class)、接口(interface)
再加一个例子进一步理解
public class test2 {
public static void main(String[] args) {
//值传递、引用传递
Count count = new Count();
int times =0;
for (int i = 0; i < 100; i++) {
increment(count, times); //在此处count相当于引用传递,把地址传了过去,而times相当于是值传递,在函数中改变的是函数中新声明的那块区域的
}
System.out.println(count.c1+" "+times);
}
public static void increment(Count temc,int times) {
temc.c1++;
times++;
}
}
在上边这个例子中,我们能看到的是最后真正被改变的值是count中的c1这个,能够改变的原因是在向函数传参的过程中,传的count这个类的对象的地址,使得函数操作的对象就是传进去的这个类的对象,这一过程为引用传递。而对于传进去times这个参数来说,函数操作的对象是在函数中新创建的那个参数,而函数外的那个参数并未传进去,传进去的只有那个参数所含有的值,这一过程称为值传递。