- 方法
1.1 概述
- 方法 就是很多条语句的集合,把这些代码放到方法中,然后就可以多次使用这个方法
- 方法目的 : 代码复用 , 使程序更加简短清晰,提高开发效率
1.2 方法声明
- 声明 :
-
修饰符列表 返回值类型 方法名 (参数列表){ 方法体 } -
修饰符列表 : 可以有,可以没有,可以有多个
-
权限修饰 : public protected private 不写 四选一
-
其他修饰 : static , synchronized abstract , final 二选一 ..... 返回值类型 : 11种数据类型中的任意一种 , 如果不需要返回值,则写 void 方法名 : 方法的名字,望文知义,驼峰命名法 参数列表 : 要做一件事,需要的必备条件,可以作为入参 可以有多个,用 , 逗号隔开 比如 int a , int b , int c.... 形参 : 在方法声明的时候,定义的参数列表 实参 : 方法调用时,实际传入的数据 方法体 : 需要执行的代码 注意 : return 终止方法运行并返回 如果有返回值类型的方法中,方法体必须有return语句 比如 public static int m1(){ return 1;// 这里的1 只要是int值即可,因为返回值为int类型 } 如果 没有返回值 那么可以写return 也可以不写 ,就算写return 也不能返回数据,只能终止运行 public static void m1(){ return; // 只有终止方法运行的功能 }
1.3 方法分类
- 方法分类
-
1 静态方法 : 使用static修饰的方法,是静态方法
-
2 成员方法 : 没有static修饰的方法是成员方法
-
3 构造方法 : 创建对象使用,先不管
- 调用 :
-
静态方法 : 类名.静态方法名(参数) , 同类中 类名可以省略
-
成员方法 : 对象引用.成员方法名(参数)
- 方法不调用不执行,调用才执行,并把结果返回到调用处
- 编写方法 只考虑功能的实现,最终这个方法被用来做什么,与声明无关
public static void main(String[] args) {
int result = Method_01.m1(123,5312);
System.out.println(result);
}
public static int m1(int a , int b){
return a+b;
}
public static void m2(){
return ;
}
1.4 入参和出参
public static void main(String[] args) {
// print_01();
// print_02(5);
int result = sum(12, 120);
System.out.println(result);
}
// 1 需求 : 向控制台打印1-10
public static void print_01() {
for (int i = 1; i < 11; i++) {
System.out.println(i);
}
}
// 2 需求 : 向控制台打印1-N的值
// 参数列表中的变量是局部变量
public static void print_02(int n) {
for (int i = 1; i <= n; i++) {
System.out.println(i);
}
}
// 3 需求 : 计算 n~m的累加加和,并返回
// ps : n和m均为整数,且 m > n
public static int sum(int n, int m) {
int sum = 0;
for (int i = n; i <= m; i++) {
sum += i;
}
return sum;
}
// 4 需求 : 给定三个整数 , 返回其中最大的一个数, ps 你可以假设 三个数不相等
public static int max(int a, int b, int c) {
if (a > b && a > c) {
return a;
} else if (b > a && b > c) {
return b;
} else {
return c;
}
}
1.5 方法重载
- 方法唯一性 :
-
方法名 和 参数
- 方法重载 : overload 方法名相同,参数列表不同
-
列表不同分为 : 个数不同和类型不同
public static void main(String[] args) {
sumInt(1, 3);
sumDouble(10.2, 2.3);
sumLong(1, 2);
sum(1, 23);
sum(1.2, 3.2);
sum(1L, 3);
System.out.println();
System.out.println(123);
System.out.println(true);
System.out.println("xxxxxxxx");
}
public static void sumInt(int a, int b) {
}
public static void sumDouble(double a, double b) {
}
public static void sumLong(long a, long b) {
}
// ----------------
public static void sum(int a, int b) {
}
public static void sum(double a, double b) {
}
public static void sum(long a, long b) {
}
- 内存分析
2.1 内存划分
- Java Runtime Data Area : java运行时区域,一般叫JVM内存
- 程序计数器 :
-
一块较小的内存区域.作用可以看做是当前程序执行的位置指示器
- 静态区/方法区 :
-
保存程序文件(class文件) 以及静态数据,方法被调用之前,也保存在静态区,内部还有运行时常量池
- VM栈 : 又叫栈内存
-
栈内存是以栈数据结构为模型开辟的一段空间, 特性是先进后出
-
栈 : 是一种数据结构,先进后出,像弹夹
- 栈的构成因素
-
栈空间 : 栈内存就是栈空间
-
栈帧 : 栈空间中的每一个栈元素 就叫栈帧(比如 弹夹中的每一个子弹 就叫栈帧)
-
栈底元素 : 第一个放进去的栈帧
-
栈顶元素 : 最后一个放进去的栈帧
- 栈操作
-
压栈 : 就是指把元素放入栈空间的过程
-
弹栈 : 就是把元素弹出去的过程
- 栈内存,是用来执行方法的,所有方法的执行,必须在栈内存进行
- 本地方法栈 :
-
用来执行一些本地方法,比如hashCode 等 , 模型和操作都和VM栈一致 , 不用管,
- 堆内存 :
-
用来保存对象
2.2 运行机制
- 运行机制
- 1 java 程序编写
- 2 javac编译,得到class文件
- 3 java命令 运行
-
3.1 开启jvm,把运行的程序载入内存,把class文件保存到静态区
-
3.2 加载完之后,JVM自动调用程序中的main方法
-
3.3 在栈内存开辟栈帧,用来执行main方法
-
如果 main方法中,没有其他方法调用,则运行完 弹栈 销毁 结束 JVM关闭
-
如果main方法中,有其他方法调用,则在main方法之上再开辟一个栈帧,用来执行新的方法,以此类推
-
但是 如果调用的方法是别的类中的方法,则需要把对应的类先加载进来
- 方法调用 : 就等于是压栈操作
- 方法执行完成 : 就等于是弹栈操作
- 加载
-
静态加载 : 指程序开始运行,就把相关的所有文件全部一次性载入内存
-
动态加载 : 程序运行开始,只载入核心文件,当用到其他文件的时候,再去加载
- java中采用动态加载机制
public static void main(String[] args) {
m1();
System.out.println(123);//3
}
public static void m1(){
m2();
System.out.println("m1执行了");//2
}
public static void m2(){
System.out.println("m2执行了");//1
}
- 递归
3.1 概述和基本使用
- 递归 : 方法中调用当前方法
- 递归思想
-
递归和迭代是等价的 就是循环
-
基本思想就是以此类推
- 应用场景 :
-
循环能做的,递归都能做,但是这种情况 优先使用循环,因为递归非常消耗内存,运行效率低
-
但是 像树状结构之类的,循环是没法做的,只能通过递归来搞定
- 常见的问题
-
所有树状结构
-
文件夹复制
-
斐波那契数列
- 难点 : 不容易理解,递归思想
-
画图,栈帧调用图
- 注意 必须有终止条件,否则就等于死循环一样,导致一直压栈不会弹栈而出现 的栈内存溢出问题
//没有终止条件会导致栈内存溢出
public static void main(String[]args){
m1();
}
public static void m1(){
m1();
}
// 1-N的累加加和
public static int sum(int n) {
if (n == 1) {
return 1;
}else{
return n + sum(n-1);
// return 5 + 10; n = 5
// return 4 + 6; n = 4
// return 3 + 3; n = 3
// return 2 + 1; n = 2
// return 1; n = 1
}
}
3.2 斐波那契数列
//1 1 2 3 5 8 13 21 34 55 89.....
public static void main(String[] args) {
int result = factorial(20);
System.out.println(result);
// System.out.println(count);
}
// static int count = 0;
public static int factorial(int n){
// count++;
if (n ==1 || n == 2) {
return 1;
}else{
return factorial(n-1) + factorial(n-2);
}
}



