方法
2020-04-16 本文已影响0人
雪上霜
-
方法:是可以完成某个特定功能的并且被重复利用的代码片段,C中是函数,Java中是方法。一个方法就是一个功能单元。
//没有方法的Java程序 public calss MethodTest{ public static void main(String[] args){ int x = 100; int y = 200; int z = x + y; System.out.println(x + "+" + y + "=" + z); int x1 = 100; int y1 = 200; int z1 = x1 + y1; System.out.println(x1 + "+" + y1 + "=" + z1); //上述的代码复用性差。功能/业务逻辑相同,为什么需要重复编写代码。直接调用相同功能即可。如果想达到代码复用,需要学习方法机制。 } }
//带有方法的Java程序 public calss MethodTest{ //主方法 public static void main(String[] args){ //程序先从main方法执行,自上而下逐行执行。 //main方法不需要手动调用,是JVM调用的,其他方法必须手动调用。 sumInt(100,200); sumInt(666,888); sumInt(111,222); } //方法定义在类体中,位置无关。 //x,y是局部变量,函数结束之后内存自动释放。 public static void sunInt(int x,int y){ int z = x + y; System.out.println(x + "+" + y + "=" + z); } }
-
方法定义,语法机制。
[修饰符列表]返回类型 方法名(形式参数列表){ 方法体 } 1.中括号的内容是可选的。 2.方法需要调用,不调用无法执行。 3.返回值类型可以是任何Java合法的数据类型,基本数据类型,引用数据类型。 4.返回值:方法的执行结束之后的结果。谁调用就返回给谁。 5.当一个方法执行结束之后,不返回值时用void关键字。 6.如果返回值不是void类型,则需要用return返回返回值类型的数据。 return 数据。 7.return返回方法的执行结果。 8.如果void,可以有return;语句。 方法名:见名知意 方法名在标识符命名规范中,要求首字母小写后面的单词首字母大写。 只要是合法标识符就行。 形式参数列表:每个参数都是局部变量,方法结束之后内存释放,个数:0-n个。 方法体:Java语句构成,是业务逻辑代码,完成某个特定功能。在方法体重的代码自上而下执行。 方法调用:方法调用才能执行。 语法: 类名.方法名(实际参数列表);
public class MethodTest{ //main方法结束之后不需要给JVM返回任何数据 public static void main(String[] args){ //调用方法 MethodTest.divide(100,200);//(100,200)是实际参数列表,类型,个数一一对应。 int ret = MethodTest.sum(100,200);//这个方法返回结果使用变量接收 //接收的数据类型与返回数据类型一致。 double ret1 = MethodTest.sum(100,200);//小容量可以自动转换为大容量类型。 //无返回值不可以接收。 byte b1 = 10; byte b2 = 20; int ret2 = sum(b1,b2); MethodTest.println(); dayin(); //第一次跨类调用。这种情况类名.不能省略了。 MyClass.dayin(); } //方法定义没有顺序要求。 public static int divide(int x,int y){ int z = x / y; return z; } public static void divide(int x,int y){ int z = x / y; System.out.println(z); } //计算两个int类型和 public static int sum(int x,int y){ return x+y; } public static void println(){ System.out.println("hello world"); } public static void dayin(){ System.out.println("hello world"); } } class MyClass{ public static void dayin(){ System.out.println("hello world"); } }
public class MethodTest{
//main函数最先执行,最后结束,main方法结束,整个程序结束。
public static void main(String[] args){
m1();
}
public static void m1(){
m2();
}
public static void m2(){
T.m3();
}
}
class T{
public static void m3(){
System.out.println("T's m3 method execute!");
}
}
public class MethodTest{
public static void main(String[] args){
for(int i = 0;i < 10;i++){
if(i == 5){
break; //终止for循环
return; //终止当前方法。
}
}
}
}
public class MethodTest{
public static void main(String[] args){
int res = m();
System.out.println(res);
int res2 = m1(true);
System.out.println(res2);
}
//程序错误:缺少返回语句
//必须保证返回int类型数据。
//第一种方案:带有else分支的一定有一个分支执行。
//第二种方案:不写else,直接返回。
//同一个域中,return之后不能再有其他代码。
public static int m(){
boolean flag = true;
//对于编译器来说,flag只是boolean类型,认为可能是false,true。
if(flag){
return 1;
System.out.println("hello"); //这个代码永远不会执行,会报错。
}
}
public static int m1(boolean flag){
return flag ? true : false;
}
}
-
JVM的内存结构
image.png
-
栈
image.png
image.png

public class MethodTest{
public static void main(String[] args){
int x = 100;
m1(x);
}
public static void m1(int i){
m2(i);
}
public static void m2(int i){
m3(i);
}
public static void m2(int i){
System.out.println(i);
}
}
-
方法执行中的内存变化
image.png
public class MethodTest{
public static void main(String[] args){
int x = 100;
m1(x);
}
public static void m1(int i){
m2(i);
}
public static void m2(int i){
m3(i);
}
public static void m2(int i){
System.out.println(i);
}
}
public class Homework{
public static void main(String[] args){
int res = jc(5);
System.out.println(res);
}
public static int jc(int n){
int res = 1;
for(int i = n;i > 1;i--){
res *= i;
}
return res;
}
public static boolean zs(int n){
if(n == 2)
return true;
for(int i = 2;i < n;i++){
if(n % i == 0){
return false;
}
}
return true;
}
public static void zsm(int n){
int i = n;
boolean flag = false;
while(true){
n++;
if(zs(n)){
System.out.println(n);
break;
}
}
/*
//上述代码升级为:
while(!zs(++n));
System.out.println(n);
*/
}
}
-
方法重载Overload
public class OverloadTest{ public staic void main(String[] args){ int x = sumInt(10,20); System.out.println(x); long y = sumLong(10L,20L); System.out.println(y); double z = sumDouble(10.0,20.0); System.out.println(z); } //以下三个方法功能相似。 //三个不同的名字缺点:代码不美观。程序员需要记忆更多的方法名称。 public static int sumInt(int a,int b){ return a+b; } public static long sumLong(long a,long b){ return a+b; } public static double sumDouble(double a,double b){ return a+b; } }
//使用方法重载机制 public class OverloadTest{ public staic void main(String[] args){ int x = sum(10,20); System.out.println(x); long y = sum(10L,20L); System.out.println(y); double z = sum(10.0,20.0); System.out.println(z); } //首先根据方法名区分,相同则根据参数类型区分。 //以下三个方法功能相似。 //三个相同的名字:易记忆。美观。 public static int sum(int a,int b){ return a+b; } public static long sum(long a,long b){ return a+b; } public static double sum(double a,double b){ return a+b; } }
-
什么时候需要考虑使用方法重载Overload。
-
在同一个类中,功能相似可以考虑将方法名一致,这样既美观又便于后期的代码编写。
-
什么时候发生方法重载:在同一个类中,方法名相同,参数列表不同。参数类型,个数,顺序都算参数列表不同。
-
方法重载与修饰符和返回值无关。
public class OverloadTest{
public static void main(String[] args){
m1();
m1(100);
}
public static void m1(){
System.out.println("void");
}
public static void m1(int a){
System.out.println("int");
}
}
public class OverloadTest{
public static void main(String[] args){
System.out.println(10);
System.out.println(10.0);
System.out.println(true);
System.out.println('a');
System.out.println("abc");
}
}
public class S{
public static void p(){
System.out.println();
}
public static void p(byte b){
System.out.println(b);
}
public static void p(short s){
System.out.println(s);
}
public static void p(int i){
System.out.println(i);
}
public static void p(long l){
System.out.println(l);
}
public static void p(double d){
System.out.println(d);
}
public static void p(boolean b){
System.out.println(b);
}
public static void p(char c){
System.out.println(c);
}
public static void p(String s){
System.out.println(s);
}
}
//将S类编译成字节码文件,只要这两个类在同一个文件中即可。
public class HelloWorld{
public static void main(String[] args){
S.p("hello world");
S.p(100);
S.p(a);
S.p(true);
S.p(100+200);
}
}
- 方法递归
public class RecursionTest{
public static void main(String[] args){
doSome();
}
//死循环
//递归没有退出条件会发生栈溢出。所以递归必须要有结束条件。
public static void doSome(){
System.out.println("doSome Begin");
doSome();
System.out.println("doSome end");//这行永远执行不到。
}
//栈溢出错误:首先检查递归的结束条件,如果没有问题可手动调整JVM的栈内存的初始化大小,可以将栈内存的空间调大点。
}
public class RecursionTest{
public static void main(String[] args){
System.out.println(sum(10));
System.out.println(res(10));
}
public static int sum(int n){
int sum = 0;
for(int i = 0;i <= n;i++){
sum += i;
}
return sum;
}
public static int res(int n){
if(n == 0){
return 0;
}
return n + res(n-1);
}
}
