/** * 关于方法: * - 什么是方法: * * 方法就是一段代码片段,并且这段代码片段可以完成某个特定功能,并且可以被重复使用 * * 方法(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");//此行代码不能执行 } }