Java 中的方法

方法

方法在调用时会在JVM栈空间内创建栈帧用于存储方法内所有数据

在编程过程中难免在实现功能上出现重复代码,从而导致代码过于冗长,不易于阅读理解

此时善用方法可以达到提高代码的可重复利用性

通过传入数据进行数据处理,可传回数据,也可以不传回(由其返回值类型决定)

main方法是一个典型的方法(程序的主入口)

方法的定义与声明

方法名命名遵循命名规则(小驼峰命名法)

方法需要定义在类中

权限修饰符 + static + 返回值类型 + 函数名称(参数列表){方法代码块}

权限修饰符:

public:公开的,类内类外谁都可以访问

private:私有的,仅供类内访问

protected:对同一包内所有类,子类均可访问

静态类型:

static:静态的,可从类外部直接访问,声明为静态的方法只能访问类内的静态变量,可选

返回值类型:

void 无返回值,此处为返回值类型,决定返回的处理后数据类型,可以是可接受的数据类型,如果是其他类型,则方法语句中需要return值,如果return后不加任何东西,则直接退出方法,如:

public static void fanc(){
	代码块;
	return;//return后不加任何值即代码运行到此处直接退出方法,可不加
}
public static int fanc(){
    代码块;
    return 0;//返回值为0,此时方法结束,在外围的运行到此处则为return值,返回的值的类型要和上面声明方法时所声明的返回类型相同
}

public static void main(String[] args){//main方法
    int i = fanc();//声明一个变量i的值为Fanc方法的返回值,调用该方法时运行方法内代码并返回值,此时Fanc() = 0,所以最后的语句等效于int i = 0;
}

参数列表:

参数列表可有可无,决定调用时需要传入的数据及类型和数量,用逗号隔开(如果有多个),为局部变量

形参和实参完全独立,因其会开辟独立的内存空间,直接复制一份为副本并对副本进行操作,具体如下图

分为形参和实参(实际传给函数的数据):

public static int fanc(int numIn){//这里numIn是形参,形参可以和外部变量名相同,但是形参间不能同名
	return = numIn++;//这里在方法调用之初会在栈中单独开辟一个空间等待传入参数
}
public static void main(String[] args){
	fanc(10);//这里的10为实参
}

方法在调用过程中的内存变化为:

public static int calculate(int numInOne , int numInTwo ){//假设创建一个方法用于计算总和,这里引用的参数为两个int整型
	int sum = numInOne + numInTwo;//创建sum整型存储和
	return sum;//返回sum值
}
public static void main(String[] args){
    int numPressOne = 1;//声明变量
    int numPressTwo = 2;
    System.out.println(calculate(numPressOne , numPressTwo));//打印调用方法后的结果
}
/*打印结果为
3
*/

方法调用前后栈的变化

需要注意的是,如果传入参数是引用类型,那么如果在方法内对其进行更改那么在全局就会改变

因为引用数据类型传入的是引用,即对象的内存地址,所以,如果方法内对该地址的内容进行更改,由于在外部的对象也指向这个地址,所以外部读取该内存的数据就是改变后的了,如:

public static void main(String[] args){
	int[] Array = new int[]{1,2,3,4,5};//创建数组对象,Array本身不含数据,只是存了数据在堆中的内存地址,假设其地址为0x123
	changeArray(Array);//将数组传入方法
}
public static void changeArray(int[] arr){//传入的实际为数组地址,arr为副本数组内容也为0x123
	arr[4] = 100;//在方法体内更改数组,实际上是直接对堆内数据进行操作,对0x123地址上的数据进行更改
}
System.out.println(Array[4]);//输出为100,读取0x123上的数据

用个简单的例子来比喻的话就是两个拆迁队他们手中有相同的地址,即引用对象本身的地址和副本内的地址,其中一个拆迁队将其拆除,那另一队到达时已经是废墟了,即,如果在方法内把这个地址的建筑物拆除了,到方法外的那个拆迁队到达的那个地址已经是拆迁后的建筑物了

具体调用过程如下图:

方法内外改变数组原理

如果需要防止这种事情发生,可以在方法内主动创建副本改变指向地址,从而达到对数组数据进行操作而不改变原数组:

public static void main(String[] args) {
    int[] arr = new int[]{1,2,3,4,5};//创建一个数组,此时为地址一
    changeArray(arr);//调用方法
    System.out.println(Arrays.toString(arr));//返回地址一的数组数据
}
public static void changeArray(int[] arrIn){//调用方法后,传入arrIn的为地址一
	int[] arrDeal = new int[arrIn.length];//创建一个新的数组,长度与原数组相同,其地址为地址二
	System.arraycopy(arrIn, 0, arrDeal, 0, arrIn.length);//将原数组数据传入新数组
	arrIn = arrDeal;//将地址二赋值给arrIn
	arrIn[4] = 100;//改变地址二内的数据
	System.out.println(Arrays.toString(arrIn));//返回地址二的数组数据
}
/*
结果如下:
[1, 2, 3, 4, 100] 方法内的数组
[1, 2, 3, 4, 5] 方法结束后的原始数组
*/

em.out.println(Arrays.toString(arrIn));//返回地址二的数组数据
}
/*
结果如下:
[1, 2, 3, 4, 100] 方法内的数组
[1, 2, 3, 4, 5] 方法结束后的原始数组
*/


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值