目录
一、方法的概念和使用
1.1方法的含义
1.2 方法的定义
1.3方法调用的执行过程
1.4实参和形参的关系
1.5没有返回值的方法
二、方法重载
2.1方法重载的含义
2.3 方法签名
三、递归
3.1 递归的概念
3.2递归的执行过程
3.3递归练习
一、方法的概念和使用
1.1方法的含义
方法就是一个代码片段. 类似 C语言中的函数.
方法的作用:
1.能够模块化的组织代码(当代码规模比较复杂时)。
2.代码被重复使用, 一份代码可以在多个位置使用。
3.让代码更好理解更简单。
4.直接调用现有方法, 不必重复敲相同代码
1.2 方法的定义
语法格式:
修饰符 返回值类型 方法名称(参数列表){
方法体
(return 返回值);
}
示例
public static boolean IsYear(int year){ if((0 == year % 4 && 0 != year % 100) || 0 == year % 400){ return true; }else{ return false; } }
注意:修饰符:现阶段直接使用public static 固定搭配;返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成void;方法名字:采用小驼峰命名;参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开;在java当中,方法必须写在类当中,方法不能嵌套定义,没有方法声明一说即不需要方法声明。
1.3方法调用的执行过程
调用过程:调用方法--->传递参数--->找到方法地址--->执行被调方法的方法体--->被调方法结束返回--->回到主调方法继续往下执行。
示例
public static int add1(int x, int y){ //x、y是形参,保存传递的数据,而main函数中的参并不改变 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); ret = add1(30, 50); System.out.println("ret = " + ret); }
注意:定义方法的时, 不会执行方法的代码,只有调用的时候才会执行;一个方法可以被多次调用。
1.4实参和形参的关系
方法的形参相当于数学函数中的自变量,形参的名字可以随意取,对方法都没有任何影响,形参只是方法在定义时需要借助的一个变量,用来保存方法在调用时传递过来的值。在Java中,实参的值永远都是拷贝到形中,形参和实参本质是两个实体。
示例
public static void main(String[] args) { int a = 10; int b = 20; swap(a, b); System.out.println("main: a = " + a + " b = " + b); } //交换数值 public static void swap(int x, int y) { int tmp = x; x = y; y = tmp; System.out.println("swap: x = " + x + " y = " + y); }
在swap函数交换之后,形参x和y的值发生了改变,但是main方法中a和b还是交换之前的值,即没有交换成功。
原因分析:实参a和b是main方法中的两个变量,其空间在main方法的栈(一块特殊的内存空间)中,而形参x和y是swap方法中的两个变量,x和y的空间在swap方法运行时的栈中,故实参a和b 与 形参x和y是两个没有任何关联性的变量,在swap方法调用时,只是将实参a和b中的值拷贝了一份传递给了形参x和y,因此对形参x和y操作不会对实参a和b产生任何影响,对于基础类型来说, 形参相当于实参的拷贝. 即传值调用。
解决办法:传引用类型参数 (例如数组来解决这个问题)
示例
public static void main(String[] args) { int[] arr = {10, 20}; swap(arr); System.out.println("arr[0] = " + arr[0] + " arr[1] = " + arr[1]); } public static void swap(int[] arr) { int tmp = arr[0]; arr[0] = arr[1]; arr[1] = tmp; }
1.5没有返回值的方法
方法的返回值是可有可无,没有时返回值类型必须写成void。
public static void main(String[] args) { int a = 10; int b = 20; print(a, b); } public static void print(int x, int y) { System.out.println("x = " + x + " y = " + y); }
二、方法重载
2.1方法重载的含义
重载就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者重载方法。
2.2方法重载的作用
方法重载不用为了对不同的参数类型或参数个数,而写多个函数。多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。注意:重载函数,方法名必须相同;参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序不同),与返回值类型是否相同无关;编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法。
示例
public static void main(String[] args) { int a = 10; int b = 20; double c = 10; double d = 20; int ret = add(a, b); System.out.println(ret); System.out.println(add(c,d)); } public static int add(int x, int y) { return x + y; } public static double add(double x, double y) { return x + y; }
2.3 方法签名
在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量,那为什么类中就可以定义方法名相同的方法呢?方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式:方法全路径名+参数列表+返回值类型,构成方法完整的名字。
方法签名中的一些特殊符号
特殊字符 | 数据类型 |
V | void |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
[ | 数组(以[开头,配合其他的特殊字符,表述对应数据类型的数组,几个[表述几维数组) |
L | 引用类型,以L开头,以;结尾,中间是引用类型的全类名 |
三、递归
3.1 递归的概念
递归是一个方法在执行过程中调用自身。递归相当于数学上的 "数学归纳法", 有一个起始条件, 然后有一个递推公式。
如:求N!
起始条件:N=1时,N!=1,起始条件相当于递归的结束条件。
递归公式:求N!,直接求不好求,可以N!=N*(N-1)!
递归的必要条件:
1.将原问题划分成其子问题,注意:子问题必须要与原问题的解法相同
2.递归出口
示例 求 N 的阶乘
public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
if (n == 1) {
return 1;
}return n * factor(n - 1)
}
3.2递归的执行过程
递归的程序的执行过程不太容易理解, 要想理解清楚递归, 必须先理解清楚 "方法的执行过程", 尤其是 "方法执行结束之后, 回到调用位置继续往下执行"。
示例 递归求 N !
public static void main(String[] args) {
int n = 5;
int ret = factor(n);
System.out.println("ret = " + ret);
}
public static int factor(int n) {
System.out.println("函数开始, n = " + n);
if (n == 1) {
System.out.println("函数结束, n = 1 ret = 1");
return 1;
}int ret = n * factor(n - 1);
System.out.println("函数结束, n = " + n + " ret = " + ret);
return ret;}
3.3递归练习
示例1 按顺序打印数字的每一位如数字1234 打印1 2 3 4
public static void func(int n){ if(n/10==0){ System.out.println(n); } else { func(n/10); System.out.println(n%10); } } public static void main(String[] args) { int a=1234; func(a); }
示例2 递归求1+2+...+10
public static int func1(int n){ if(n==1) return 1; else return n+func1(n-1); } public static void main(String[] args) { int a=10; System.out.println(func1(a)); }
示例3 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19。
public static int func2(int n){ if(n/10==0){ return n; } else { return n%10+func2(n/10); } } public static void main(String[] args) { int a=1729; System.out.println(func2(a)); }
使用递归方法时可能会由于进行了大量的重复运算导致程序执行速度非常慢,要根据具体情况来判断是使用递归还是循环的方法。