方法,必须由其所在类或对象调用才有意义。参数的方法,参数分为形参和实参:
形参:方法声明时的参数。
实参:方法调用时实际传给形参的参数
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本 (复制品)传入方法内(in模式),而参数本身不受影响。
在java中根据数据类型划分,参数又可以分为基本数据类型参数和引用数据类型参数。
形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参 。
形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参。
基本数据类型的参数传递
实例:
package com.qwy;
/**
* 基本数据类型的参数值传递
* @author qwy
*
*/
public class ValueTransferTest {
public static void main(String[] args) {
int num = 3;
System.out.println("调用change()方法之前的num的值:"+num);//3
change(num);
System.out.println("调用change()方法之后的num的值:"+num);//3
}
public static void change(int num){
System.out.println("change()修改之前的num的值:"+num);//3
num = 5;
System.out.println("change()修改之后的num的值:"+num);// 5
}
}
执行结果:
调用change()方法之前的num的值:3
change()修改之前的num的值:3
change()修改之后的num的值:5
调用change()方法之后的num的值:3
前三个输出结果基本没有任何异议,第四个结果为什么打印的是3而不是5呢?这里需要从内存角度来思考:
- 首先我要确定定义在方法中的变量为局部变量,局部变量存放位置为栈内存。
- 当main方法执行到int num = 3时 ,在栈内存中存储了变量 num且值为3.所以紧接着输出的num变量的值为3,好理解
- 当在main方法中执行到change(num)时,此时num作为实参传入change()方法,且此时num的值为3 ,也就是change(3).
- 此时开始执行change方法,在change(int num)方法中参数num作为形参接收上一步的3,而此时的num参数有作为change方法的局部变量,所以此时站内存中也会存在change的一个局部变量num ,且值为3,所以change方法的第一打印输出3.
- 紧接着在change方法中给局部变量重新赋值 num = 5,所以紧跟的输出语句输出5.
- 此时change()方法执行完毕,又回到了main方法中。此时change方法中的局部变量num,由于方法执行完毕,所以num失效(此时num出栈),但是main方法还没有执行完毕,也就是main方法存储在栈中的num变量还没有失效,值依然是3.所以此时输出3也就好理解了。
示意图:
引用数据类型的参数传递
实例:
Data类:
package com.qwy;
public class Data {
int num;
}
ValueTransferTest2类:
package com.qwy;
/**
* 基本数据类型的参数值传递
* @author qwy
*
*/
public class ValueTransferTest2 {
public static void main(String[] args) {
Data obj= new Data();
obj.num=3;
System.out.println("调用change()方法之前的num的值:"+obj.num);//3
change(obj);
System.out.println("调用change()方法之后的num的值:"+obj.num);//5
}
public static void change(Data obj){
System.out.println("change()修改之前的num的值:"+obj.num);//3
obj.num = 5;
System.out.println("change()修改之后的num的值:"+obj.num);// 5
}
}
运行结果:
调用change()方法之前的num的值:3
change()修改之前的num的值:3
change()修改之后的num的值:5
调用change()方法之后的num的值:5
从打印结果看,引用数据类型跟基本数据类型传值不同。就这个例子来看:
- 首先要知道引用数据类型的属性(成员变量)值存储在堆内存中。
- 当main方法执行Data ojb= new Data();开辟堆内存0x3000,并将该地址赋值给变量ojb.
- 执行obj.num=3;后堆内存存储的是3.所以此时打印obj.num的值为3.
- 执行到change(obj)时,将ojb的地址传递给change(Data obj)方法。此时虽然obj作为change方法的局部变量,但是此时ojb保存的是obj的地址,跟main方法创建的ojb是同一个实例,指向同一个堆内存块。所以change方法第一个打印语句仍然输出3.
- 当程序执行到了change方法的obj.num = 5时,因为main方法和change方法的ojb都指向同一个堆内存地址。所以此时堆内存存在了变量值为5.change方法自然此时再打印便打印5.
- change方法运行完毕,但是堆内存中仍然存在main方法的引用,此时main调用obj.num,自然是被change方法修改过的(change方法和main方法操作的是同一个对象),所以此时调用obj.num,也就输出5.
图示:
====================================================================================================
自己也是最近才开始写文章,看到大家都分享自己的经验给别人。我也是受益者之一,做人不能只懂的索取而不去回馈,所以也将自己学习的知识分享给大家。我不能保证每个问题都讲的是对的,毕竟我也是个学习者。如果有地方写得不对或理解有误的,也希望大家给指出,我当非常感谢。编写过程也不易,也希望大家给个赞,关注下本人。这也能激励我继续分享。
====================================================================================================