方法概念及使用
什么是方法
- 方法就是一段代码片段,类似 C 语言的函数
- 方法作用
a)代码模块化:代码逻辑复杂时,拆分代码
b)代码复用:一份代码多处使用
c)可读性强:代码逻辑清晰,便于维护
d)开发效率高:直接调用现成方法,不用重复写代码方法定义
语法格式
修饰符 返回值类型 方法名称([参数类型 形参 ...]){ 方法体代码; [return 返回值;] }- 修饰符:现阶段固定写 public static
- 返回值类型:
有返回值:写对应数据类型,返回值必须和类型匹配
无返回值:写void,不能写 return 数据- 方法名:小驼峰命名,例如isLeapYear、add
- 参数列表:类型 变量名
多个参数逗号隔开
无参括号留空, 这里叫形参- 方法体:大括号内,方法执行逻辑代码
- return:①结束方法;②把结果返回给调用处
void 方法可直接写return,用来结束方法- Java 语法硬性规则
a)方法必须写在类里面
b)方法不能嵌套定义,方法里面不能再写另一个方法
c)Java 没有 “方法声明” 这一说,方法要写完整
判断闰年
public static boolean isLeapYear(int year) { if((year%4==0)&&(year%100!=0)||(year%400==0)) { return true; } else { return false; } }两个整数相加
public static int add(int a,int b) { return a+b; }
方法调用
重点:定义方法不会执行代码,只有调用才执行
- 调用格式:方法名(实参);
- 实参:
调用方法时传入的真实数据,给形参赋值
参数要做到:类型匹配、顺序匹配、个数匹配- 有返回值:可以用变量接收返回结果;也可以直接打印、参与运算
- 无返回值 (void):直接写方法名(实参); 不能拿变量接收
方法调用过程
main 方法启动执行;遇到方法调用,跳转到被调用方法内部执行
实参的值拷贝赋值给形参
- 执行方法体代码;遇到
return,方法结束,回到调用位置- main 继续往下执行
内存角度:
每次调用方法,会开辟一块独立栈内存;
方法内的局部变量只属于当前方法,方法执行完毕,局部变量销毁
- 阶乘求和 1!+2!+3!+4!+5!
好处:fac 方法被多次复用,代码简洁,避免写多重循环//计算n的阶乘 public static int fac(int n) { int result=1; for(int i=1;i<=n;i++) { result*=i; } return result; } public static void main(String[] args) { int sum=0; for(int i=1;i<=5;i++) { sum+=fac(i); } System.out.println(sum); }
实参和形参的关系
- 形参:方法定义处 getSum(int n),n就是形参,属于方法局部变量
- 实参:调用的时候getSum(10),10就是实参
- Java 中基本数据类型传参:值拷贝
实参把自己的数据复制一份给形参;
形参和实参是两块完全独立内存,修改形参,不会影响外面实参变量
经典坑:交换两个数字(基本类型无法交换)
public static void swap(int x,int y) { int temp=x; x=y; y=temp; } public static void main(String[] args) { int a=1; int b=2; System.out.println("交换前:"+"a = "+a+" b = "+b); swap(a,b); System.out.println("交换后:"+"a = "+a+" b = "+b); }- 原因:
只是把 a、b 的值拷贝一份给 x,y;
swap 内部交换的只是副本,main 里 a,b 不受影响
基本类型做不到在方法内部交换外面变量的值
解决方法:用引用类型才可以实现交换
返回值 return
有返回值方法:return 值; 返回值类型必须和方法声明返回类型一致
- void 无返回值方法:
可以写return;(不带数值),用来提前结束方法;
不能 return 数据- 返回值可以直接参与运算
- 一个方法中,return执行之后,方法立刻结束,后面代码不再运行
return 两个作用
- 将结果返回给方法调用处
- 终止当前方法执行
方法重载
- 什么是方法重载
在同一个类中,方法名相同,参数列表不同,就构成方法重载
作用:功能相似的方法复用同一个方法名,不用记多个方法名,编译器根据传入实参自动匹配调用哪个方法- 数列表不同的 3 种情况(满足其一即可)
参数个数不同void show(int a){} void show(int a,int b){}参数类型不同
void show(int a){} void show(double a){}参数顺序不同
void show(int a,double b){} void show(double a,int b){}- 不参与重载判断
返回值类型不参与重载判断
只改返回值,参数完全一样,不能构成重载,编译报错// 错误,不是重载 public static int test(int x){} public static double test(int x){}修饰符(public/static)也不参与重载判断
//方法重载 public static int add(int a,int b) { return a+b; } public static int add(int a,int b,int c) { return a+b+c; } public static double add(double a,double b) { return a+b; } public static void main(String[] args) { int x=1; int y=2; int ret=add(x,y); System.out.println(ret); // 3 double a=1.0; double b=2.0; double ret2=add(a,b); System.out.println(ret2); //3.0 int i=1; int j=2; int k=3; int ret3=add(i,j,k); System.out.println(ret3); }
方法签名
- 为什么同一个类可以有同名方法
同一个作用域不能有相同标识符,但是类里可以写多个名字一样的方法,靠的是方法签名区分- 方法签名:由方法名 + 参数列表(参数个数、类型、顺序)组成;
返回值不属于方法签名- 编译后 JVM 靠完整签名来区分多个同名方法,这就是方法重载
public static int add(int x, int y){ return x + y; } public static double add(double x, double y){ return x + y; } public static void main(String[] args) { add(1,2); //调用 int版本add add(1.5, 2.5); //调用 double版本add }两个方法方法名都叫add,但是参数列表不一样,方法签名不同,编译后在字节码中是两个完全不同的方法
递归
递归的概念
- 递归
一个方法(函数)在执行过程中调用自身,就叫递归
类比数学里数学归纳法:要有起始条件(递归出口)+递推公式- 递归两个必要条件
a)原问题可以拆成子问题,子问题和原问题解法相同
b)递归出口(终止条件,防止无限递归)//递归 求阶乘 public static int factor(int n) { //递归出口 if(n==1) { return 1; } return n*factor(n-1);//调用自身,递推 }- 函数调用时,当前函数会暂停,等子递归执行完返回结果,再继续完成本层计算
- 按顺序打印数字每一位(例:1234 → 1 2 3 4)
- 求数字各位之和(例:1729 →1+7+2+9=19)