1 方法
1.1 什么是方法?有什么用?(可以先看一下,一个程序如果没有方法,会出现什么问题?)
方法(英语单词:Method)方法是可以完成某个特定功能的并且可以被重复利用的代码片段。
在c语言中,这个方法被称为“函数”。在java中不叫函数,叫做方法。
你定义了一个/抽取了一个方法出来,而这个方法却无法完成某个功能,那么你抽取的这个方法毫无意义。一般一个方法就是一个“功能单元”。
假设在以后的开发中,某个功能是可以独立抽取出来的,建议定义为方法,这样以后只要需要这个功能,那么直接调用这个方法即可,而不需要重复编写业务逻辑代码。
案例:
/* 对于一个java程序来说,如果没有“方法”,会存在一个什么样的问题? 代码无法得到复用。(怎么提高复用性,可以定义方法,然后需要使用该功能的时候,直接调用一下方法即可。这样代码就得到复用了。) */ public class MethodTest01{ public static void main(String[] args){ // 需求1: 请编写程序,计算100和200的求和 int x = 100; int y = 200; int z = x + y; System.out.println(x +"+"+ y +"="+ z); // 需求2: 请编写程序,计算666和888的求和 // 这个需求2实际上和需求1是完全相同的,只不过具体求和的“数据不同” int a = 666; int b = 888; int c = a + b; System.out.println(a +"+"+ b +"="+ c); /* 需求1和需求2本质上是相同的,只不过参与运算的数值不同, 代码编写了两份,显然代码没有得到重复利用,专业术语叫做“复用性”差 功能/业务逻辑既然相同,为什么要重复编写代码,代码能不能写一次,以后要是需要再次使用该“业务/需求”, 直接调用就可以了。 如果想达到代码复用,那么需要学习java语言中的方法机制。 */ } }
案例:
/* 这个程序是一个体验程序,你看不懂,你只需要去体验就行了。 体验一下方法的好处。 注意: 程序开始执行的时候是先执行main方法。 因为main方法是一个入口。 在java语言中所有的方法体中的代码都必须遵循自上而下的顺序依次逐行执行。 这个必须记住 main方法不需要程序员手动调用,是由JVM调用。 但是除了main方法之外其他的方法,都需要程序员你手动调用,方法只有调用的时候才会执行,方法不调用是不会执行的。 */ public class MethodTest02{ // 方法定义在类体当中, // 方法定义的先后顺序没有关系。都可以。 public static void main(String args[]){ /*int x = 100; int y = 200; sunInt(x,y);*/ // 需求1: 请编写程序,计算100和200的求和 sunInt(100,200); // 需求2: 请编写程序,计算666和888的求和 sunInt(666,888); // 需求3: 请编写程序,计算111和222的求和 sunInt(111,222); } // 专门在这个类体当中定义一个方法,这个方法专门来完成求和。 // x y z 在以下的sunInt方法中都属于局部变量 // 局部变量有一个特点:方法结束之后,局部变量占用的内容会自动释放。 public static void sunInt(int x,int y){// 程序自上而下的顺序一次逐行执行。 int z = x + y; System.out.println(x +"+"+ y +"="+ z); } // 这里并没有讲解方法的定义,以及方法的调用。 }
案例:
/* 1 方法怎么定义,语法机制是什么? [修饰符列表] 返回值的数据类型(void的意思就是不返回任何结果,如果不是void,那么你必须要有“return 值;”) 方法名(形式参数列表) { 方法体; // return 返回值的数据类型(值); } 注意:[]这个符号叫做中括号,以上中括号[]里面的内容表示不是必须的,是可选的。 方法体由java语句构成 方法定义之后需要去调用,不调用是不会执行的。 1.1 关于修饰符列表: 修饰符列表不是必选项,是可选项。目前为止大家统一写成:public static 后面你就应该怎么写了。 1.2 关于返回值类型: 第一:返回值类型可以是任何类型,只要是java中合法的数据类型就行,数据类型包括基本数据类型和引用数据类型, 也就是说返回值类型可以是:byte short int long float doule boolean char String...... 第二:什么是返回值? 返回值一般指的是一个方法执行结束之后的结果。 结果通常是一个数据,所以被称为“值”,而且还叫返回值。 方法就是为了完成某个特定的功能,方法结束之后大部分情况下都是有一个结果的,而体现结果的一般都是数据。 数据得有类型。这就是返回值类型。 方法执行结束之后的返回值实际上是给了调用者,这个返回值返回给main了。 第三:当一个方法执行结束不返回任何值的时候,返回值类型也不能空白,必须写上void关键字。所以void表示该方法执行结束后不返回任何结果。 第四:如果返回值类型“不是void”,那么你在方法体执行结束的时候必须使用“return”值;这样的语句来完成“值”的返回,如果没有“return”值;那么这个返回结果会报错。 return值;这样的语句作用是什么?作用是“返回值”,返回方法的执行结果。 第五:一定要注意:只要有“return”关键字的语句执行,当前方法必然结束。 return只要执行,当前所在的方法就会结束,记住:不是整个程序结束。 第六:如果返回值类型是void,那么在方法体当中不能有“return 值;”这样的语句。 但是可以有“return;”语句。这个“return;”的作用就是用来终止当前方法的。 第七:除了void之外,剩下的都必须有“return 值;”这样的语句。 1.3 方法名 方法名要见名知意。(驼峰命名方式。) 方法名标识符命名规范当中,要求首字母小写,后面的单词每个首字母大写。 只要是合法的标识符就行。 1.4 形式参数列表: 简称:形参 注意:形式参数列表中的每一个参数都是局部变量,方法结束之后内存释放。 形参的个数是0~n个。 public static void sum(){} public static void sum(int x){} public static void sum(int x,int y){} public static void sum(int x,int y,double d,String s){} 形参有多个的话使用逗号隔开。逗号是英文下的","。 形参的数据类型起决定性作用,形参对应的变量名是随意的。 1.5 方法体由java语句构成。java语句以";"结尾。 方法体当中编写的是业务逻辑代码,完成某个特定功能。 在方法体中的代码遵循自上而下的顺序依次逐行执行。 在方法体中处理业务逻辑代码的时候需要数据,数据来源就是这些形参。 2 方法定义只有怎么调用呢? 方法必须调用才能执行。 怎么调用?语法是什么? 类名.(调用)方法名(实际参数列表); 实参和形参的类型必须一一对应,另外个数也要一一对应。 */ public class MethodTest03{ //方法定义在这里可以。 // main方法结束之后不需要给JVM返回任何结果。 public static void main(String[] args){ // 调用方法 /* 错误: 不兼容的类型: String无法转换为int MethodTest03.divide("abc",5);*/ // MethodTest03.divide("abc",5); /* 错误: 无法将类 MethodTest03中的方法 divide应用到给定类型; MethodTest03.divide(); ^ 需要: int,int 找到: 没有参数 原因: 实际参数列表和形式参数列表长度不同 */ //MethodTest03.divide(); // (10,2)叫做实际参数列表,简称实参。 // 实参和形参必须一一对应,类型要对应,个数也要对应。 MethodTest03.divide(100,5); // 调用方法 // 怎么去接收这个方法的返回值? // 使用变量来接收这个方法的返回值。 // 注意:变量的定义需要指定变量的数据类型。 // 变量的数据类型是什么呢? int jieGuo = MethodTest03.sum(100,5); System.out.println(jieGuo); // jieGuo变量可以是double类型吗? // double是大容量。int是小容量。自动类型转换。 double jieGuo2 = MethodTest03.sum(100,5); System.out.println(jieGuo2); // 对于没有返回值的方法,变量能接收吗? // divide方法结束没有返回值。不能接收。 // 错误: 不兼容的类型: void无法转换为int // int i = MethodTest03.divide(100,5); // 当一个方法有返回值的时候,我们可以不不接收吗? // 你可以返回值,但是我可以选择不要你这个值。这个是允许的。 // 只不过这样没有意义,一般程序返回了执行结果,都是需要接收这个结果的。 // 我们可以不接收,但是这个返回值该返回还是要返回的,只不过不用变量接收。 // 以下代码虽然没有使用变量接收这个返回值,但是这个值还是返回了。 // 返回之后内存马上释放,因为没有使用变量接收。 MethodTest03.sum(100,5); byte b1 = 10; // int a = b1; byte b2 = 20; int result = sum(b1,b2); // 自动类型转换 (b1,b2)是实际类型参数 System.out.println(result); } // 计算两个int类型数据的和。 public static int sum(int a,int b){ //(int a,int b)是形式参数列表 return a + b; } // 方法定义在这里也可以,没有顺序要求。 // 业务是什么?计算两个int类型数据的商。 // 方法执行结束之后返回执行结果。 //错误: 缺少返回语句 /*public static int divide(int x,int y){ int z = x / y; }*/ //错误: 不兼容的类型: String无法转换为int /*public static int divide(int x,int y){ int z = x / y; return "abc"; }*/ // 可以的 /*public static int divide(int x,int y){ int z = x / y; return z; }*/ // 可以的 /*public static int divide(int x,int y){ return x / y; }*/ // 如果我不需要执行结束之后的返回值? // 这个结果我希望直接输出。 // 错误: 不兼容的类型: 意外的返回值 /*public static void divide(int x,int y){ return x / y; }*/ // 可以的 /*public static void divide(int x,int y){ return;// 用来终止这个方法的 }*/ // 可以的 //public static void divide(int x,int y){} // 定义是可以的,但是没有调用 public static void divide(int x,int y){ System.out.println(x / y); } }
案例:
/* 再方法调用的时候,什么时候“类名”是可以省略的。什么时候不能省略? a()方调用b()方法的时候,a和b方法都在同一个类中,“类名.”可以省略。 如果不在同一个类名“类名.”不能省略。 */ public class MethodTest04{ public static void daYin3(){ System.out.println("吴欣麟是个帅逼!"); } public static void main(String[] args){ // 调用println()方法。 MethodTest04.daYin(); MethodTest04.daYin2(); MethodTest04.daYin3(); //类名.可以省略吗? MyClass.daYin(); daYin2(); daYin3(); // 第一次跨类调用。 // 像这种情况下:“类名”就不能省略了。 MyClass.daYin(); MyClass.daYin2(); MyClass.daYin3(); } public static void daYin(){ System.out.println("Hello World!1"); } public static void daYin2(){ System.out.println("Hello World!2"); } } class MyClass{ public static void daYin(){ System.out.println("垃圾乙方"); } public static void daYin2(){ System.out.println("克扣人"); } public static void daYin3(){ System.out.println("吴欣麟是个帅逼!你说得对!"); } }
案例:
//别自乱阵脚 任何一个方法体当中的代码都是遵循自上而下的顺序依次执行的。 /* 执行结果: main开始 m1开始 m2开始 m3开始 T's m3 method execute m3结束 m2结束 m1结束 main结束 main方法最先执行,并且main方法是最后一个结束。 main结束,整个程序就结束了。 */ public class MethodTest05{ public static void main(String[] args){ System.out.println("main开始"); // 调用m1方法 m1(); System.out.println("main结束"); } public static void m1(){ //调用程序不一定写到main方法中,不要把main方法特殊化。 //main方法也是一个普通方法。 System.out.println("m1开始"); m2(); System.out.println("m1结束"); } // m2方法可以条用T类的m3方法吗? public static void m2(){ System.out.println("m2开始"); T.m3(); System.out.println("m2结束"); } } class T{ public static void m3(){ System.out.println("m3开始"); System.out.println("T's m3 method execute"); System.out.println("m3结束"); } }
案例:
/* break;语句和return;语句有什么区别? 不是一个级别。 break;用来终止switch和离他最近的循环。 return;用来终止离他最近的一个方法。 */ public class MethodTest06{ public static void main(String[] args){ // main方法的返回值类型是void,表示没有返回值。 for(int i = 0 ; i < 10 ; i++){ if(i == 5){ // break;// 终止for循环 return; // 错误: 不兼容的类型: 意外的返回值 // return 10; } System.out.println("i == " + i); } System.out.println("Hello World!"); } }
案例:
/* 大家分析以下代码,编译器会报错吗? */ public class MethodTest07{ public static void main(String[] args){ // 调用方法 int result = m(); System.out.println(result); // 调用x方法 int result1 = x(true); System.out.println(result1); // 再次调用x方法 int result2 = x(false); System.out.println(result2); } // 错误: 缺少返回语句 /* public static int m(){ boolean flag = true;// 编译器不负责运行程序吗,编译器只负责讲道理。 // 对于编译器来说,编译器只知道flag变量是boolean类型 // 编译器会认为flag有可能是false,有可能是true if(flag){ // 编译器觉得:以下这行代码可能会执行,当然也可能不会执行 // 编译器为了确保程序不出现任何异常,所以编译器说:缺少返回语句 return 1; } } */ // 怎么修改这种程序呢? // 第一种方法:带有else分支的可以保证一定会有一个分支执行。 /*public static int m(){ boolean flag = true; if(flag){ return 1; }else{ return 0; } }*/ // 第二种方法:该方案实际上是方案1的变形。 // return语句一旦执行,所在的方法就会结束。 /*public static int m(){ boolean flag = true; if(flag){ return 1; } return 0; }*/ /* // 在同一个域当中,“return语句”下面不能在编写其他代码,编写之后编译报错。 public static int m(){ boolean flag = true; if(flag){ return 1; // 错误: 无法访问的语句 //System.out.println("Hello1"); } // 这行代码和上面的代码hello1的区别是:不在同一个域中。 System.out.println("Hello1"); return 0; // 错误: 无法访问的语句 // System.out.println("Hello1"); } */ // 三目运算符有的时候会让代码很简练。 public static int m(){ boolean flag = true; return flag ? 1 : 0; } public static int x(boolean flag){ return flag ? 1 : 0; } }