1. 方法
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 ;
}
如果 没有返回值 那么可以写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) {
int result = sum ( 12 , 120 ) ;
System. out. println ( result) ;
}
public static void print_01 ( ) {
for ( int i = 1 ; i < 11 ; i++ ) {
System. out. println ( i) ;
}
}
public static void print_02 ( int n) {
for ( int i = 1 ; i <= n; i++ ) {
System. out. println ( i) ;
}
}
public static int sum ( int n, int m) {
int sum = 0 ;
for ( int i = n; i <= m; i++ ) {
sum += i;
}
return sum;
}
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 ( 1 L, 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. 内存分析
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 ) ;
}
public static void m1 ( ) {
m2 ( ) ;
System. out. println ( "m1执行了" ) ;
}
public static void m2 ( ) {
System. out. println ( "m2执行了" ) ;
}
3. 递归
3.1 概述和基本使用
* 递归 : 方法中调用当前方法
*
* 递归思想
* 递归和迭代是等价的 就是循环
* 基本思想就是以此类推
*
* 应用场景 :
* 循环能做的, 递归都能做, 但是这种情况 优先使用循环, 因为递归非常消耗内存, 运行效率低
* 但是 像树状结构之类的, 循环是没法做的, 只能通过递归来搞定
*
* 常见的问题
* 所有树状结构
* 文件夹复制
* 斐波那契数列
*
* 难点 : 不容易理解, 递归思想
* 画图, 栈帧调用图
*
* 注意 必须有终止条件, 否则就等于死循环一样, 导致一直压栈不会弹栈而出现 的栈内存溢出问题
public static void main ( String[ ] args) {
m1 ( ) ;
}
public static void m1 ( ) {
m1 ( ) ;
}
public static int sum ( int n) {
if ( n == 1 ) {
return 1 ;
} else {
return n + sum ( n- 1 ) ;
}
}
3.2 斐波那契数列
public static void main ( String[ ] args) {
int result = factorial ( 20 ) ;
System. out. println ( result) ;
}
public static int factorial ( int n) {
if ( n == 1 || n == 2 ) {
return 1 ;
} else {
return factorial ( n- 1 ) + factorial ( n- 2 ) ;
}
}