方法
一堆代码的集合,创建空间存储,并设置名字,可以通过名字找到,能代码复用、易维护、易扩展、更灵活.
声明 : 修饰符列表 返回值类型 方法名 (参数列表) {方法体}
修饰符列表 : 可以有,可以没有,可以有多个,但是有些是不能同时出现的,多个修饰符没有先后顺序.
权限控制相关: public , private , protected , 不写(默认包权限) 四选一
static 表示静态,不加则为成员 ; final 和 abstract 不能同时出现
返回值类型 : 执行完之后是否要将结果反馈给调用处, 可以写11种数据类型中任意一种,如果不需要返回值则写void(要返回的数据是什么类型,这里就写什么类型)
如果指定了返回值,则方法体内必须有 return 语句 : 终止方法运行 , 将数据返回到调用处
方法名 : 符合命名规则即可
参数列表 : 可以有多个,也可以没有, 用逗号隔开
方法调用
前缀.方法名(参数) //如果调用当前类中的静态方法,类名可以省略
重载
java中方法可以重名
方法重载 : 方法名相同,参数列表不同 ; 个数不同或类型不同
目的 : 使用方便,相同功能,相同方法名,方便记忆
内存分析
Java在运行时进行内存划分
静态区/方法区 : 保存静态资源文件,比如静态变量,方法,class文件等
VM栈 : 以栈数据结构为模型,创建的一块空间,主要用于执行方法
栈数据结构特征 : 先进后出 , 即栈顶元素是最后放进去的 , 栈底元素是第一个放进去的
栈帧是栈数据结构中的元素,称为栈帧 , 把栈帧放到栈空间的过程叫压栈 , 把栈帧在栈空间弹出去的过程叫弹栈 . 每当调用一个方法的时候,该方法就会在栈内存中开辟一个栈帧,并压栈到栈空间,开始执行,方法执行完后,弹栈,栈帧销毁
堆内存 : 保存类对象和成员变量及成员方法
运行
1、编码 , 程序员编写java程序
2、编译 , 把.java文件编译成class文件
3、运行 , JVM开机,将所运行的类载入内存空间中的静态区
3.1 加载完成后,JVM会自动调用该类的main方法(只要是方法调用,就会在栈内存中开辟栈帧并压栈)
3.2 如果main方法中,有别的方法调用 : 如果调用的是其他类中的方法,则先把对应类加载到静态区,然后再栈内存中开辟栈帧 ; 如果调用的是当前类中的方法,则直接在栈内存开辟栈帧
3.3 如果被调用的方法中,还有其他方法调用,则继续开辟栈帧压栈,一直到栈顶元素,执行完成,弹栈,返回上一个栈帧继续执行
3.4 直到main栈帧弹栈,则整个程序生命周期终止
递归
递归和迭代(循环)是等价的 , 循环可以做的,递归也能做,但是递归能做的,循环不一定能做 . 递归需要频繁压栈弹栈,比较消耗内存,并且效率较低,所以循环能完成的,就不要使用递归.
递归的应用场景有树状结构,目录遍历等,以及计算阶乘、斐波那契数列等数学问题上.有直接递归 和间接递归两种形式:
直接递归 : 方法中调用当前方法(自己调用自己)
间接递归 : 两个方法相互调用
public static void main(String[] args) {
m1();
}
// 直接递归
public static void m1(){
// 注意 递归 也有符合 循环三要素
// 初始值,终止条件,步长,否则会死循环
// Exception in thread "main" java.lang.StackOverflowError
// 因为一直压栈,不会弹栈,导致栈内存移出
m1();
}
// 间接递归
public static void m2(){
m3();
}
public static void m3(){
m2();
}
public static int m1(int m) {
if (m == 1) {
return 1;
}
return m + m1(m - 1);
}