目录
[⽰例⼆: 实现⼀个两个整数相加的⽅法](#⽰例⼆: 实现⼀个两个整数相加的⽅法)
本文章内容大纲:
1.本文通过制作咖啡的类比,系统讲解了Java方法的概念和使用。方法类似于C语言中的函数,能够模块化组织代码、实现复用、提高可读性。
2.文章详细介绍了方法的定义语法、参数传递机制(形参与实参的关系)、返回值处理,并通过多个示例演示了方法的具体应用。特别强调了方法重载的概念,即同名方法通过不同参数列表实现不同功能。
3.最后深入讲解了递归的原理和执行过程,包括阶乘计算、数字逐位打印、数列求和等经典案例。通过理论与实践相结合的方式,帮助读者全面掌握Java方法的核心知识点。
一:方法的简单理解
想象⼀下你在家⾥制作咖啡。你有⼀个"制作咖啡"的过程,这个过程其实就可以看作⼀个函数,怎么 理解呢?
制作咖啡的步骤:
准备材料:咖啡⾖、⽔、糖、⽜奶
磨咖啡⾖:将咖啡⾖磨成粉
煮⽔:将⽔煮沸
冲泡:将热⽔倒⼊咖啡粉中,浸泡⼏分钟
添加配料:根据个⼈喜好添加糖或⽜奶
享⽤:最后,倒⼊杯中,享⽤美味的咖啡
接受⻝材(参数),执⾏⼀系列步骤(代码),最后得到⼀杯咖啡(返回值)
说白了,就是C语言里面的函数,只不过它在java里面叫做方法
二:⽅法概念及使⽤
1.什么是⽅法(method)
⽅法就是⼀个代码⽚段.类似于C语⾔中的"函数"。⽅法存在的意义(不要背,重在体会)
-
是能够模块化的组织代码(当代码规模⽐较复杂的时候).
-
做到代码被重复使⽤,⼀份代码可以在多个位置使⽤.
-
让代码更好理解更简单.
-
直接调⽤现有⽅法开发,不必重复造轮⼦.
2.⽅法定义
⽅法语法格式
修饰符 返回值类型 ⽅法名称 ( 参数类型 形参 ...) {
⽅法体代码 ;
return 返回值 ;
}
总结:
"制作咖啡"就像⼀个函数,接受⻝材(参数),执⾏⼀系列步骤(代码),最后得到⼀杯咖啡(返回 值)。每次你想喝咖啡时,只需要调⽤这个"函数",⽽不需要每次都重复所有步骤。这样不仅提⾼了效率,也让整个过程变得更加简单和有条理
函数名称:makeCoffee
参数:coffeeBeans (咖啡⾖) 、 water (⽔) 、 sugar (糖)、 milk (⽜奶)
返回值:⼀杯咖啡
3.书写⽅法的⽰例
⽰例⼀:实现⼀个函数,检测⼀个年份是否为闰年
看代码:
java
import java.util.Scanner;
public class Test {
public static void isLeapyear(int year){
if((year%4==0&&year%100!=0)||(year%400==0)){
System.out.println(year+"是闰年");
}else{
System.out.println(year+"不是闰年");
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int year = scanner.nextInt();
isLeapyear(year);
}
}
结果:

⽰例⼆: 实现⼀个两个整数相加的⽅法
看代码:
java
public class Test {
public static void add(int a ,int b){
int c =a+b;
System.out.println(c);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num1 = scanner.nextInt();
int num2 = scanner.nextInt();
add(num1,num2);
结果:

【注意事项】
1. 修饰符:现阶段直接使⽤public static固定搭配
2. 返回值类型:如果⽅法有返回值,返回值类型必须要与返回的实体类型⼀致,如果没有返回值,必须写成void
3. ⽅法名字:采⽤⼩驼峰命名
4. 参数列表:如果⽅法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使 ⽤逗号隔开
5. ⽅法体:⽅法内部要执⾏的语句
6. 在Java当中,⽅法必须写在类当中
7. 在Java当中,⽅法不能嵌套定义
8. 在Java当中,没有⽅法声明这一说法
4.⽅法的调⽤
上面的代码示例里面我就已经调用了,和C语言一样,这里我就不过多的讲解了
定义⽅法的时候,不会执⾏⽅法的代码.只有调⽤的时候才会执⾏.
调⽤⽅法的时候,需要使⽤⽅法名+参数列表的形式进⾏调⽤
如果⽅法有返回值,需要接收返回值结果
此外:
1. ⼀个⽅法可以被多次调⽤
2. 使⽤⽅法,避免使⽤⼆重循环,让代码更简单清晰.
5.实参和形参的关系
⽅法的形参相当于数学函数中的⾃变量,⽐如:1+2+3 +...+n的公式为sum(n)=((1+n)*n)/2
Java中⽅法的形参就相当于sum函数中的**⾃变量n**,⽤来接收sum函数在调⽤时传递的值的。形参的名字可以随意取,对⽅法都没有任何影响,形参只是⽅法在定义时需要借助的⼀个变量,⽤来保存⽅ 法在调⽤时传递过来的值。
看代码:
java
public static int getSum(int N) { // N是形参
return (1+N)*N / 2;
}
public static void main(String[] args) {//调⽤⽅法
int ret = getSum(10); // 10是实参,在⽅法调⽤时,形参N⽤来保存10
System.out.println("ret = " + ret);
}
结果:

图表解析:

注意:
在Java中,实参的值永远都是拷⻉到形参中,形参和实参本质是两个实体
上述代码进⾏修改:
java
public static int getSum(int N) { // N是形参
return (1+N)*N / 2;
}
public static void main(String[] args) {//调⽤⽅法
int ret = getSum(10.9); // 10是实参,在⽅法调⽤时,形参N⽤来保存10
System.out.println("ret = " + ret);
结果会报错:

注意:
实参传值给形参,必须做到类型匹配,顺序匹配,个数匹配
经典案例:交换实参的值
利用方法来进行写这个代码
java
public class Test {
public static void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(" 交换前: a = " + a + " b = " + b);
//调用交换两个数的方法
swap(a, b);
System.out.println(" 交换后: a = " + a + " b = " + b);
}
结果是错误的,没有交换成功:
原因分析:
实参a和b是main⽅法中的两个变量,其空间在main⽅法的栈(⼀块特殊的内存空间)中,⽽形参x和y 是swap⽅法中的两个变量,x和y的空间在swap⽅法运⾏时的栈中。
因此:实参a和b与形参x和y是 两个没有任何关联性的变量,在swap⽅法调⽤时,只是将实参a和b中的值拷⻉了⼀份传递给了形参 x和y,因此对形参x和y操作不会对实参a和b产⽣任何影响。
在Java当中是⽆法获取栈上的局部变量的地址的,如果要发⽣实参的交换,我们需要具备类和对象的 知识,后续在讲解完类和对象之后,我们会讲解⼀个合理的做法。
6.返回值
⽅法的返回值是⽤来接收⽅法运⾏之后,需要传递出去的值的。有的⽅法有返回值,有的⽅法没有返 回值。
如果有返回值的情况下,我们需要注意返回值的数据类型需要匹配。
看代码,还是上面那个代码:
java
public static int getSum(int N) { // N是形参
return (1+N)*N / 2;
}
public static void main(String[] args) {//调⽤⽅法
int ret = getSum(10); // 10是实参,在⽅法调⽤时,形参N⽤来保存10
System.out.println("ret = " + ret);
}
该⽅法getSum返回值是int,需要使⽤int来进⾏接收
如果没有返回值,我们需要注意,不能接受该⽅法返回值,返回值类型为void
看代码:
java
public static void print(int x, int y) {
System.out.println("x = " + x + " y = " + y);
}
public static void main(String[] args) {
int a = 10;
int b = 20;
print(a, b);
//错误做法
int ret = print(a, b);//编译报错
}
结果会报错:

图表分析:

返回值可以⽀持链式表达式:
题⽬:计算连续数字1到N之间的和,将其计算得到的结果扩⼤为2倍
看代码:
java
public static int getSum(int x){
return (1+x)* x / 2;
}
public static void main(String[] args) {
int ret = getSum(10) * 2;
System.out.println("ret = " + ret);
}
结果:

上述代码中:getSum(10) * 2利⽤了⽅法的返回值作为新的表达式的⼀个值参与了运算
总结:
1. 返回值在接收过程当中需要匹配
2. 没有返回值的情况下,⽅法的返回值类型为void
3. ⼀个⽅法是否有返回值需要视情况⽽定
三:⽅法重载
1.为什么需要⽅法重载
问题:当既想计算两个整数相加,也想计算两个⼩数相加的时候,此时会出现参数类型不匹配的情况
看代码:
java
//完成加法运算
public static int add1(int x, int y) {
return x + y;
}
public static void main(String[] args) {
//整数
int a = 10;
int b = 20;
int ret = add1(a, b);
System.out.println("ret = " + ret);
//浮点数
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add1(a2, b2);
System.out.println("ret2 = " + ret2);
}
结果会报错:

由于参数类型不匹配,所以不能直接使⽤现有的add⽅法.
⼀种⽐较简单粗暴的解决⽅法如下:
提供2个⽅法,分开计算
看代码:
java
//完成加法运算
public static int add1(int x, int y) {
return x + y;
}
public static double add2(double x, double y) {
return x + y;
}
public static void main(String[] args) {
//整数
int a = 10;
int b = 20;
int ret = add1(a, b);
System.out.println("ret = " + ret);
//浮点数
double a2 = 10.5;
double b2 = 20.5;
double ret2 = add2(a2, b2);
System.out.println("ret2 = " + ret2);
}
结果:

上述代码确实可以解决问题,但不友好的地⽅是:需要提供许多不同的⽅法名,⽽取名字本来就是让⼈头疼的事情。
那能否将所有的名字都给成 add 呢?
2.⽅法重载的概念
在⾃然语⾔中,⼀个词语如果有多重含义,那么就说该词语被重载了,具体代表什么含义需要结合具 体的场景。
在Java中⽅法也是可以重载的。
在Java中,如果多个⽅法的名字相同,参数列表不同,则称该⼏种⽅法被重载了。
看代码:
java
public static int add4(int x, int y) {
return x + y;
}
public static double add4(double x, double y) {
return x + y;
}
public static double add4(double x, double y, double z) {
return x + y + z;
}
public static void main(String[] args) {
int a=add4(1, 2);//调⽤add(int, int)
double b=add4(1.5, 2.5);//调⽤add(double, double)
double c =add4(1.5, 2.5, 3.5);//调⽤add(double, double, double)
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
结果:

注意:
1.⽅法名必须相同
2.参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序必须不同)
3.与返回值类型是否相同⽆关
4.编译器在编译代码时,会对实参类型进⾏推演,根据推演的结果来确定调⽤哪个⽅法
3.⽅法签名
在同⼀个作⽤域中不能定义两个相同名称的标识符。
⽐如:⽅法中不能定义两个名字⼀样的变量,那为什么类中就可以定义⽅法名相同的⽅法呢?
⽅法签名即:经过编译器编译修改过之后⽅法最终的名字。
具体⽅式:⽅法全路径名+参数列表,构成⽅法完整的名字
具体介绍可以查看官网:https://docs.oracle.com/javase/specs/jls/se17/html/jls-8.html#jls-8.4.2
看代码:
java
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);
Add(1.5, 2.5);
}
上述代码经过编译之后,然后使⽤JDK⾃带的javap反汇编⼯具查看
具体操作:
-
先对⼯程进⾏编译⽣成.class字节码⽂件
-
在控制台中进⼊到要查看的.class所在的⽬录
-
输⼊:javap-v字节码⽂件名字即可
看图表:

⽅法签名中的⼀些特殊符号说明:

四:递归
1.递归的概念
⼀个⽅法在执⾏过程中调⽤⾃⾝,就称为"递归".
递归相当于数学上的"数学归纳法",有⼀个起始条件,然后有⼀个递推公式.
例如,我们求N!
起始条件:N=1的时候,N!为1.这个起始条件相当于递归的结束条件.
递归公式:求N!,直接不好求,
可以把问题转换成N!=>N*(N-1)!
递归的必要条件:
1. 将原问题划分成其⼦问题,注意:⼦问题必须要与原问题的解法相同
2. 递归出⼝
代码⽰例:递归求N的阶乘
看代码:
java
public static int factor(int n){
if(n==1){
return n;
}else {
return n * factor(n - 1);
}
}
public static void main(String[] args) {
int n = 5;
//求阶乘
int ret = factor(n);
System.out.println("ret = " + ret);
}
结果:

2.递归执⾏过程分析
递归的程序的执⾏过程不太容易理解,要想理解清楚递归,必须先理解清楚"⽅法的执⾏过程",尤其是 "⽅法执⾏结束之后,回到调⽤位置继续往下执⾏"
还是上面那个5的阶乘的代码来进行分析和解释
看图表:

程序按照序号中标识的(1)->(8)的顺序执⾏.
关于"调⽤栈":
1.⽅法调⽤的时候,会有⼀个"栈"这样的内存空间描述当前的调⽤关系.称为调⽤栈.
2.每⼀次的⽅法调⽤就称为⼀个"栈帧",每个栈帧中包含了这次调⽤的参数是哪些,返回到哪⾥继续执 ⾏等信息.
3.后⾯我们借助IDEA很容易看到调⽤栈的内容
3.递归练习
代码⽰例1
按顺序打印⼀个数字的每⼀位(例如1234打印出1234)
看代码:
java
public static void main(String[] args) {
//题目:利用方法,输入1234 打印1 2 3 4
Scanner scanner =new Scanner(System.in);
int num = scanner.nextInt(); //用户输入
int ret = Print(num);
}
public static int Print(int x){
//1234想要得到1就用/10和%10的方法
if(x>9){
Print(x/10); //利用递归
}
System.out.print(x%10);
return x;
}
结果:

代码⽰例2
递归求1+2+3+...+10
看代码:
java
public static void main(String[] args) {
//题目:计算1-10的和
int ret = sum(10);
System.out.println(ret);
}
public static int sum(int x){
if(x==1){
return 1;
}else {
return x+sum(x-1); //运用递归公式
}
}
结果:

代码⽰例3:
求斐波那契数列的第N项
介绍:即前两个数字相加等于第三个数字
详细介绍可以看链接:https://baike.sogou.com/v267267.htm?fromTitle=%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97
看代码:
java
public static void main(String[] args) {
//求斐波那契数的第N项
int ret = Fib(40);
System.out.println(ret);
}
public static int Fib(int x){
if(x==1||x==2){
return 1;
}
else{
return Fib(x-1)+Fib(x-2);
}
}
第40项的数字的结果:

以上就是我们的全部内容了!!!!!!!!!