/**
* 关于方法:
* - 什么是方法:
* * 方法就是一段代码片段,并且这段代码片段可以完成某个特定功能,并且可以被重复使用
* * 方法(method)也叫函数(function)
* * 方法定义在类体当中,在一个类中可以定义多个方法,方法编写的位置没有先后顺序,可以随意
* * 方法体当中不能再定义方法
* * 方法体由java语句构成,方法体中的代码遵守自上而下的顺序依次执行
*
* - 方法怎么定义,语法结构是:
* [修饰符列表] 返回值类型 方法名(形式参数列表){
* 方法体(java语句)
* }
* 修饰符列表:
* * 修饰符列表:是可选项,不是必须的 目前统一写成:public static
* 在修饰符列表中如果有static关键字,其调用方法为:类名.方法名(实际参数列表)
*
* 返回值类型:
* * 返回值类型: 一个方法是可以完成某个特定功能的,功能结束后需要返回执行结果,这个结果是
* 具体的数据,这个数据就是返回值,这个数据的类型就是返回值类型。
* * 返回值类型包括:基本数据类型和所有的引用数据类型,方法执行结束之后也可能不需要返回任何数据
* 这时返回值类型的位置需要写"void"关键字
* * 返回值类型若不是void,表示这个方法执行结束之后必须返回一个具体数值,当方法执行结束的时候,
* 没有返回任何数据,编译器就会报错。返回数据的数据类型必须和返回值类型一致。
* * 返回值语法格式: return 字面值;
* * 当返回值类型是void的时候,在方法体当中不能编写“return 字面值;”这样的语句,但是可以编写
* return; 这样的语句。
* * 只要带有return关键字的语句执行了,return语句所在的方法就结束了。
* * 要求在控制台输出结果与是否有返回值无关,这是两个概念
*
* 方法名:
* * 只要是合法的标识符就行
* * 最好见名知意
* * 最好是动词
* * 首字母小写,后面每个单词首字母大写
*
* 形式参数列表(形参):
* * 形参是局部变量
* * 形参的个数可以是0~N个
* * 多个形参之间用半角逗号隔开
* * 形参中起决定性作用的是形参的数据类型
* * 方法被调用的时候,实际给这个方法传递的真实数据被称为:实际参数,简称:实参
* * 实参与形参必须满足:数量相同,类型一一对应
*
* 方法体:
* * 必须由大括号括起来
* * 方法体中的代码有顺序,遵循自上而下的原则依次执行
* * 方法体由java语句构成,每条java语句以半角分号结尾
*
*
* 注意:
* * 方法只是定义没有调用是不会执行的
* * 方法被调用后开始执行,执行过程中还可以调用其他方法
* * 方法调用的时候实参和形参要求个数和数据类型对应相同,类型不同时要求能够进行自动类型转换
* * 方法的调用:
* - 方法的修饰符列表中有static关键字,完整的调用方式为:类名.方法名(实参列表);
* - 如果两个方法在同一个类体中,"类名."可以省略
*
*
* 建议在一个java源文件当中只定义一个class,这样比较清晰
*
* 当方法的返回值类型不是void的时候
* - 要求方法必须保证百分之百执行"return 字面值;"这样的语句来完成值的返回,没有这样的语句编译器会报错
* - 当调用了有返回值的方法,方法返回了一个值,对应调用者来说可以选择不接收,但是大多数情况都会选择接收,
* 接收的方法是使用变量来接收,接收时变量的类型必须和返回值类型一致,或者可以自动类型转换
*
* 关于return语句:
* - 带有return关键字的java语句只要执行,其所在的方法执行结束。
* - 在"同一个作用域"当中,return语句下面不能编写任何代码,因为这些代码永远执行不到
*
*方法执行时内存的变化:
* - 方法只定义,不调用,是不会执行的,并且在JVM中也不会给方法分配“运行所属”的内存空间,只有在调用这个方法的时候,
* 才会动态的给这个方法分配所属的内存空间
* - 在JVM内存划分上有三块主要内存空间(还有其他的)
* * 方法区内存
* * 堆内存
* * 栈内存 (栈数据结构见D:\java\栈数据结构)
* 常见的数据结构:数组、队列、栈、链表、二叉树、哈希表......
* - 方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候,将其放到了方法区当中,所以JVM中的三块主要内存空间,
* 方法区最先有数据,他存放了代码片段
* - 代码片段虽然在方法区内存中只有一份,但可以被重复调用,每次调用该方法的时候,需要给该方法分配独立的运行场所,在栈内存中分配
*
* - 方法在被调用的瞬间,栈会给该方法分配内存空间,会在栈中发生压栈动作,方法执行结束之后,给该方法分配的内存空间会全部释放,
* 此时发生弹栈动作
* * 压栈:给方法分配内存空间
* * 弹栈:释放该方法的内存空间
* - 局部变量在“方法体”中声明,局部变量内存在方法运行阶段在栈中分配
*
* 关于方法重载:(又名:overload)
* - 什么时候考虑方法重载?
* 功能相似的时候,尽可能让方法名相同。(但是功能不同/不相似的时候,需要尽可能让方法名不同)
* - 什么条件满足之后构成方法重载?
* * 在同一个类当中
* * 方法名相同
* * 参数列表不同(数量不同、顺序不同、类型不同)
* - 方法重载和什么有关系,和什么没关系?
* * 方法重载和方法名+参数列表有关
* * 方法重载和返回值类型无关
* * 方法重载和修饰符列表无关
*
* 关于方法的递归调用:
* - 什么是递归?
* 方法自己调用自己
* a(){
* a();
* }
* - 递归是相当耗费栈内存的,递归算法能不用的时候尽量不要使用
* - 递归时经常发生这样的错误:java.lang.StackOverflowError 栈内存溢出错误 错误只要发生就无法挽回 就会发生JVM停止工作
* - 递归必须有结束条件,不然一定会发生栈内存溢出错误
* - 递归即使有了结束条件,也可能发生栈内存溢出错误,因为递归的太深了
*
* 注意:递归是能不用尽量不用,但是有些情况还必须依靠递归来完成
*/
public class 方法 {
public static void main(String[] args) {
System.out.println("main begin");
f1();
System.out.println("main over");
}
public static void f1() {
System.out.println("f1 begin");
f2();
System.out.println("f1 over");
}
public static void f2() {
System.out.println("f2 begin");
f3();
System.out.println("f2 over");
}
public static void f3() {
System.out.println("f3 begin");
System.out.println("f3 over");
}
}
/*
以上程序输出结果为:形象表明“先入后出,后入先出。”
main begin //先入
f1 begin
f2 begin
f3 begin //后入
f3 over //先出
f2 over
f1 over
main over //后出
*/
/**
* 注意:return 和 break 语句不同
*/
class ReturnAndBreak{
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
if (i == 5){
break;//break终止的是当前for循环
}
System.out.println("i --->" + i);
}
System.out.println("break over");
for (int i = 0; i < 10; i++) {
if (i == 5){
return;//return终止的是当前方法,所以System.out.println("return over");不能被执行
}
System.out.println("i =====>" + i);
}
System.out.println("return over");//此行代码不能执行
}
}