方法可以减少重复代码,分解复杂操作。
修饰符 返回值类型 方法/函数名(参数类型 参数名,...){ 方法体; return 返回值; }
public static void test(int a){ System.out.println(a); }
主要有权限修饰符、static、final、abstract 等,此处暂不详细讨论。
如果没有返回值,类型写成 void;如果有返回值,return 返回值的数据类型和声明的返回值类型必须一致。
由参数类型和参数名组成,可以看成作用域在方法内的局部变量,负责接收外部参数,调用函数时传递参数实际就是给参数赋值。
可变参数:个数不定的参数,必须是参数列表的最后一个,语法是在数据类型后面加三个点“... ”,实际上会转为数组参数。
返回值类型为 void 时,return 不是必需的,没有 return 时,执行到方法结尾自动返回调用方。
return 可以用于方法内的任何地方,用来提前结束方法,返回调用方。
public static void test(){ int a = 1; int b = 2; if(a == b){ return; } System.out.println("a 不等于 b"); }
方法调用可以看作一个无条件跳转,跳转到对应方法的指令处开始执行,碰到 return 语句或者方法结尾的时候,再执行一次无条件跳转,跳转回调用方,执行调用方法后的下一条指令。
计算机系统主要使用栈内存来存放方法调用过程中需要的数据,包括参数、返回地址,以及方法内定义的局部变量,返回值不太一样,可以简单认为内存中存在一个专门的 返回值存储器。
每调用一次方法,都会将相关方法的数据入栈,调用结束出栈,main 方法的数据在栈的最下面。
public class Sum { public static void main(String[] args){ int d = Sum.sum(1,2); System.out.println(d); } public static int sum(int a,int b){ int c = a + b; return c; } }
如上,程序从 main 方法开始,main 方法入栈,main 方法有一个 args 参数用来接收用户输入,然后定义了一个局部变量 int d
,接收 sum 方法的返回值。
调用 sum 方法,sum 方法入栈,传入参数 1、2 以及返回地址,sum 方法中定义了一个局部变量 int c
,存储参数 a + b 计算的结果,最后 return 返回。
在返回之前,返回值暂时保存到了专门的返回值存储器中。
在返回之后,指令指示器跳转到返回地址处,sum 方法出栈,然后继续往下执行 main 方法。
方法自己调用自己,直到遇到终止条件才会 return 返回,而方法调用主要是通过栈来存储相关数据,每调用一次方法就会在栈内存中开辟一块空间,当递归调用次数过多时,可能导致内存溢出。
public static int factorial(int n){ if(n == 1){ return 1; } return n * factorial(n-1); }