方法是什么?
方法是可以完成某个特定的功能的并且可以被重复利用的代码片段,方法的出现,让代码有了很强大复用性
方法定义:
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
形式参数列表:
简称:形参
形式参数列表中的每一个参数都是"局部变量",方法结束后内存释放,形参的个数有(0-n)个,形参有多 个的话,使用","隔开,是英文的逗号, 形参的数据类型起决定性作用,形参的变量名随意
方法体:
由java语句构成,方法体中编写的代码是业务逻辑代码,完成某个特定的功能,在方法体中处理业务逻辑 代码需要的数据,数据来源就是这些形参
注解:在写方法时参数是形参,而在调用有参数的方法时,这个参数列表为实参(实际参数列表),形参和实参必须一一对应,类型对应,个数对应。
返回值类型:
- 返回值一般指的是一个方法结束之后的结果,方法就是为了完成某个特定的功能,方法结束后,大部分都有一个结果,而体现结果的一般都是数据,数据得有类型,这就是返回值类型
- 返回值类型可以是任何类型(基本数据类型/引用数据类型)
- 返回值类型不能不写,当一个方法执行结束不返回任何值时,必须写void关键字
- 返回值类型不是void,那么在方法执行结束的时候必须使用"return 值"这样的语句来完成"值"的返回,不然会编译报错
- 如果返回值类型是void,那么在方法体当中不能有"return 值",这样的语句,但是可以有"return;",这样的语句。
注解:"return;"作用终止当前方法,只要有"return ;"关键字的语句执行,当前方法必然结束,但是不是整个程序结束,而写上System.exit(0);语句, 运行时则终止程序的执行,强行退出JVM
注意:方法定义的先后顺序没有关系,方法定义在类体中,但是在java语言中所有的方法体中的代码都必须遵循自上而下的顺序依次逐行执行。
方法调用的时候,该方法需要内存空间,在栈中分配,而且方法只有在调用的时候才会在栈中分配空间,并且调用时就是压栈,分配空间,方法执行结束后,该方法需要的空间就会释放,此时发生弹栈动作
方法调用时参数的传递问题:
参数传递的时候,和类型无关,不管是基本数据类型还是引用数据类型,统一都是将变量(盒子)中保存的那个值复制一份,传递下去,但是这个值可能是一个数字100,也可能是对象的内存地址(内存地址也是一个值),就一句话:不管是哪一种数据类型的传递,都是将变量中保存的那个值复制一份传递过去。
注解:栈中存储方法运行需要的内存,以及栈中存储方法的局部变量
局部变量有一个特点:方法结束之后,局部变量占用的内存会自动释放
注意:程序开始执行的时候是先执行main方法。因为main方法是程序入口,main方法不需要程序员手动调用,是由JVM调用的,但是除了main方法其他方法都需要程序员手动调用才能被执行。在使用方法时,自定义的方法可以调用main方法,但是没有意义,容易出现无限调用,一个方法不能再另外一个方法里声明(方法与方法之间关系是平级关系)
方法重载(overload)
什么情况下考虑使用方法重载机制?
当多个方法功能相似的时候,建议将方法名定义为一致的,这样代码美观,又方便编程(容易记忆,方便使用)
注意:方法重载不能随便使用,如果功能不相似,就不要使用
满足什么条件的时候构成了方法重载?
- 在同一个类中
- 方法名相同
- 形式参数列表不同(参数个数不同,参数数据类型不同,参数顺序不同)
方法重载优点:代码美观、方便代码的编写
方法覆盖/重写(Override)
构成方法覆盖的条件
-
方法覆盖发生在具有继承关系的父子类,这是首要条件
-
覆盖之后的方法与原方法具有相同的返回值类型、相同的方法名、相同的形式参数列表
使用方法覆盖的注意事项:
-
私有的方法不能被继承,所以不能覆盖/重写
-
构造方法也不能被继承,所以也不能覆盖/重写
-
覆盖/重写之后的方法不能比原方法拥有更低的访问权限,可以更高
-
覆盖/重写之后的方法不能比原方法抛出更多的异常,可以相同和减少
-
方法覆盖/重写只和方法有关,与属性无关
-
静态方法不存在覆盖/重写
注解:不是静态方法不能覆盖/重写,而是覆盖意义不大,方法覆盖/重写只针对实例方法,私有不能覆盖,静态不谈覆盖
什么时候会考虑使用"方法覆盖/重写"?
子类继承父类之后,当继承过来的方法无法满足当前子类的业务需求时,子类对这个方法进行从新编写,直接把父类的方法复制到子类,重写方法体(方法中的代码),其他不改变
注解:方法覆盖/重写是为了实现多态,同时为了增强类的重要性和复用性,当子类对父类继承过来的方法进行"方法覆盖/重写)"之后,子类调用该方法的时候,一定执行覆盖之后的方法
方法递归
什么是方法递归?
方法自身调用自身。
注意:使用递归的时候,必须添加结束条件,没有结束条件,会发生栈内存溢出错误。但是当递归有结束条件,并且结束条件合法的时候,也可能会发生栈内存溢出错误。原因:递归太深,栈内存不够了
栈内存溢出错误:StackOverflowError,原因:栈内存不够
方法递归简单例子:
1 public class Test {
2 public static void main(String[] args) {
3 int add = add(10);
4 System.out.println(add);
5 }
6 public static int add(int n) {
7 if (n ==1) {
8 return 1;
9 }
10 return n +add(n - 1);
11 }
12 }