Java基础-方法的使用(超详细的总结)

导读:本篇文章讲解 Java基础-方法的使用(超详细的总结),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Java的方法

学习目标

方法是什么?

  • 方法是一种语法结构,它可以把一段代码封装成一个功能,以方便重复调用。

使用方法的好处是?

  • 提高了代码的复用性
  • 让程序的逻辑更清晰

关于方法我们应该学会什么?

  • 怎么定义方法: 方法有很多不同形式的写法,我们需要掌握在不同的业务场景下写出合适的方法形式
  • 怎么调用方法: 方法定义出来是拿来调用的,只能调用才能让方法跑起来
  • 方法的内存图: 方法在内存中具体是怎么去工作的
  • 方法的参数传递机制: 方法的参数传递原理是什么样的,需要注意什么问题(面试热点)
  • 方法其他常见形式、技术: 方法在开发中常见的开发形式:方法重载和方法递归

方法定义和调用

1.方法完整的定义形式、调用

方法定义的完整格式如下:

修饰符  返回值类型  方法名( 形参列表 ){
  方法体代码(需要执行的功能代码)
    return 返回值;
}

示例:定义一个方法对2个整数求和并返回

// 修饰符: public static
// 返回值类型: int
// 方法名: sum
// 参数列表: int num1, int num2(形参列表可以没有, 可以有很多)
public static int sum(int num1, int num2) {
  	// 方法执行的代码
    int result = num1 + num2;
  	// 方法的返回值
    return result;
}

方法的调用:

  • 方法必须调用才可以跑起来,调用格式方法名(…);
public static void main(String[] args) {
  	// 调用sum返回结果
    int res1 = sum(10, 20);
    int res2 = sum(30, 40);

  	// 输出函数的返回结果
    System.out.println(res1);
    System.out.println(res2);
}

public static int sum(int num1, int num2) {
    int result = num1 + num2;
    return result;
}

使用方法的注意点:

  • 方法的修饰符:暂时都使用public static 修饰

  • 方法申明了具体的返回值类型,内部必须使用return返回对应类型的数据

  • 形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值

定义一个方法真正需要关注的就两点:1、分析方法是否需要申明返回值类型;2、分析方法是否需要接收参数。

2.方法的其他定义形式、调用

方法的其他写法:

  • 方法定义时:返回值类型、形参列表可以按照需求进行填写

注意事项:

  • 如果方法不需要返回结果返回值类型必须申明成void(无返回值), 此时方法内部不可以使用return返回数据。

  • 方法如果没有参数,或者没有返回值类型申明为void可以称为无参数、无返回值的方法,依次类推。

示例: 打印三次hello world, 无需参数和返回值

public static void main(String[] args) {
  	// 调用hello
  	hello()
}

// 无返回值, 返回值类型声明成void
public static void hello() {
    System.out.println("Hello World");
    System.out.println("Hello World");
    System.out.println("Hello World");
}

3.方法常见问题

方法的编写顺序无所谓

  • 定义的方法在main方法的上面和下面都是可以的

方法与方法之间是平级关系不能嵌套定义

  • 例如: main方法中是无法在定义方法的

方法的返回值类型为void(无返回值),方法内则不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return必须返回对应类型的数据

return语句下面,不能编写代码,因为永远执行不到,属于无效的代码

方法不调用就不执行, 调用时必须严格匹配方法的参数情况

有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用

方法的案例

学完方法的基本使用, 可以写几个案例来练习方法的使用

1.计算1-n的和返回

需求:定义一个方法,方法中计算出 1-n (包含n)的和并返回

分析

  • 根据格式编写方法 —-> 因n不固定,故方法需要声明形参接收;要返回结果,还需申明返回值类型。

  • 方法内部使用 for 循环计算出 1-n 的和并返回。

演示代码:

public static void main(String[] args) {
		// 传入n为5
    System.out.println(sum(5));
}

public static int sum(int n) {
		int result = 0;
		for (int i = 1; i <= n; i++) {
				result += i;
		}
		return  result;
}

2.判断整数是奇数还是偶数

需求:传入一个整数,然后调用方法,把整数交给方法,在方法中输出该数为奇数还是偶数

分析

  • 根据格式编写方法 —-> 因要传入数据给方法,方法需要声明形参接收。

  • 方法内部使用if语句判断,并输出对应的结论。

public static void main(String[] args) {
		// 调用check, 传入参数为6
  	check(6) // 6是一个偶数
  	// 调用check, 传入参数为3
    check(3) // 3是一个奇数
  	
}

// 无需返回值, 将返回值类型定义为void
public static void check(int n) {
		if (n / 2 == 0) {
				System.out.println(n + "是一个奇数");
		} else {
        System.out.println(n + "是一个偶数");
    }
}

3.数组求最值改方法实现

需求:定义一个方法, 传入一个数组给方法, 方法返回数组的最大值

分析:

  • 根据格式编写方法: 要返回最大值,需要申明返回值类型; 需要接收数组, 需要申明形参列表
  • 方法内部找出数组的最大值并返回。
public static void main(String[] args) {
		int[] nums = {25, 26, 10, 30, 1, 60};
		System.out.println(arrMax(nums));	// 60
}

public static int arrMax(int[] arr) {
		int max = 0;
		for (int i = 0; i < arr.length; i++) {
				if (arr[i] > max) {
						max = arr[i];
				}
		}
		return max;
}

方法调用的内存图

方法没有被调用的时候,在方法区中的字节码文件中存放

方法被调用的时候,需要进入到栈内存中运行

1.调用流程 – 内存图解(一)

  • 下面代码时如何执行的呢
public class Test {
  public static void main(String[] args) {
    		int sum = add(10, 20);
        System.out.println(sum);
  }
  public static int add(int a, int b ){
    int c = a + b; 
 		return c;  
  }
}
  • 代码会先执行main方法, 首先main方法会进入栈内存
  • 执行main方法时, 执行到int sum = add(10, 20);时, 发现main方法中又调用了add方法,
  • 那么会先去执行add方法, add方法也会进入栈内存开始执行

在这里插入图片描述

  • 当add方法执行完成后, 此时c的值已经是30, add方法就会弹出栈内存
  • add方法弹出栈内存后, 会继续执行main方法的输出语句: System.out.println(sum);

在这里插入图片描述

  • main方法执行完成后同样会弹出栈内存
  • 此时我们程序也已经全部运行完成

在这里插入图片描述

2.调用流程 – 内存图解(二)

  • 我们继续看看下面稍微复杂一点的代码, 它的执行流程是怎样的
  • 输出结果的顺序是: 吃饭, 学习, 睡觉
public class Demo2Method {
  	public static void main(String[] args) {
    		study();
  	}
  	public static void sleep(){
    		System.out.println("睡觉");
  	}
  	public static void eat(){
    		System.out.println("吃饭");
  	}
  	public static void study(){
    		eat();

    		System.out.println("学习");

    		sleep();
  	}
}
  • 方法区会有四个方法: 分别是main , study , sleep , eat
  • 首先我们会执行main方法, main方法进入栈内存执行, 执行main方法的study();语句时, 会调用study方法
  • 那么study方法会进入栈内存中执行, 执行study方法的eat();语句时, 会调用eat方法
  • eat方法又会进入到栈内存中执行, 执行System.out.println("吃饭");方法, 输出吃饭

在这里插入图片描述

  • eat方法执行完成后, 会弹出栈内存
  • 继续执行study方法的System.out.println("学习");语句, 输出学习

在这里插入图片描述

  • 继续执行study的sleep();语句, 那么就会调用sleep方法
  • sleep方法进入栈内存, 并且执行System.out.println("睡觉");语句, 输出睡觉

在这里插入图片描述

  • sleep执行完成, sleep方法弹出栈内存
  • 此时study同样也执行完成, stud方法弹出栈内存
  • study执行完成的话, main方法也执行完成, main方法也弹出栈内存
  • 此时代码全部执行完毕, 栈内存也已经清空

在这里插入图片描述

方法参数传递机制

1.值传递

Java中基本类型的参数传递机制:值传递

  • 在传输实参给方法的形参的时候,并不是传输实参变量本身, 而是传输实参变量中存储的值,这就是值传递

比如下面代码中, 我们是将a的值: 10, 传给了change方法, 并不是直接将a这个变量传给了change方法

public class Test {
		public static void main(String[] args) {
    		int a = 10;
    		change(a); 
  	}
  	public static void change(int c){

  	}
}

可能这样说起来还是比较抽象, 我们通过一个面试题, 并画图给大家解释:

  • 理解下面三个地方的System.out.println(a);语句分别输出什么
public class Test {
  	public static void main(String[] args) {
    		int a = 10;
    		change(a); 
      	System.out.println(a); // 10
  	}
  	public static void change(int a){
      	System.out.println(a); // 10
    		a = 20;
    		System.out.println(a); // 20
  	}
}
  • 方法区中两个方法: main方法和change方法
  • main方法进入栈内存中先执行
  • 执行到main方法的change(a)语句时, change方法会进入栈内存中执行
  • 同时, 会将a = 10的值10传给change方法中的a, 那么change方法中的a的值也保存的是10
  • 执行change方法的第一条System.out.println(a);语句, 输出10

在这里插入图片描述

  • 输出完成后, 执行change方法中的a = 20;语句, 此时change方法中的a会改变成20
  • 然后执行change方法的第二条System.out.println(a);语句, 输出为20

在这里插入图片描述

  • change方法执行完成, 弹出栈内存
  • 回到main方法, 继续执行main方法的System.out.println(a);语句
  • main方法的a并没有改变, 输出结果依然为10

在这里插入图片描述

2.引用传递

Java中引用类型的参数传递机制:引用传递

  • 引用传递, 传递的是变量名中保存的地址 , 这就是引用传递

我们同样通过一个例子, 画图给大家分析什么是引用传递:

  • 这个例子和刚刚的类似, 只不过传递的值是一个数组
public class Test {
  	public static void main(String[] args) {
    		int[] arrs = new int[]{10, 20, 30};
    		change(arrs);
    		System.out.println(arrs[1]); // 222
  	}
  	public static void change(int[] arrs){
      	System.out.println("方法内部2:"+arrs[1]); // 20
    		arrs[1] = 222;
    		System.out.println("方法内部2:"+arrs[1]); // 222
  	}
}
  • 方法区中有两个方法: main和change
  • main方法先进去栈内存中, 执行int[] arrs = new int[]{10, 20, 30};语句
  • 执行这一语句, 会在堆内存中开辟一个空间保存数组, 并将这个空间的地址赋值给arrs这个变量

在这里插入图片描述

  • 继续执行change(arrs);语句, 此时change方法进入栈内存执行
  • 同时将main方法的arrs这个变量的地址, 传给change方法的arrs
  • 然后继续执行change方法的第一个System.out.println("方法内部2:"+arrs[1]);语句, 输出20

在这里插入图片描述

  • 继续执行change方法arrs[1] = 222;语句, 通过地址找到数组, 将数组第二个元素修改为222
  • 执行第二个System.out.println("方法内部2:"+arrs[1]);语句, 输出结果为222

在这里插入图片描述

  • change方法执行完成, 弹出栈内存
  • 继续执行main方法的System.out.println(arrs[1]);语句
  • main方法同样根据地址去找数组, 由于和change方法的地址一样, 所以找到的数组也是同一个, 此时数组的第二个元素已经被修改, 那么main方法的输出数组第二个元素应该为222

在这里插入图片描述

方法参数传递案例

1.打印整型数组内容

需求:

  • 设计一个方法用于输出任意整型数组的内容,要求输出成如下格式:
  • “该数组内容为:[11, 22, 33, 44, 55]”

分析:

  • 定义一个方法,要求该方法能够接收数组,并输出数组内容。 —> 需要参数吗?需要返回值类型申明吗?
  • 定义一个静态初始化的数组,调用该方法,并传入该数组。

示例代码:

public class methodDemo03 {
    public static void main(String[] args) {
        int[] nums = {10, 20, 66, 88, 99};
        showArr(nums);
    }

    public static void showArr(int[] arr) {
        System.out.print("该数组的内容为: [");
        if (arr.length > 0 && arr != null) {
            for (int i = 0; i < arr.length; i++) {
                System.out.print(i == arr.length - 1? arr[i]: arr[i] + ", ");
            }
        }
        System.out.println("]");
    }
}

2.查询数组元素索引

需求:

  • 设计一个方法可以接收整型数组,和要查询的元素值;最终要返回元素在该数组中的索引,如果数组中不存在该元素则返回 -1。

分析:

  • 定义方法,接收整型数组,查询的元素值,在方法体中完成元素查询的功能。—> 是否需要参数、返回值类型?
  • 定义数组,调用该方法,并指定要搜索的元素值,得到返回的结果输出。

示例代码:

public class methodDemo04 {
    public static void main(String[] args) {
        int[] nums = {10, 30, 66, 88, 99};
        System.out.println(queryIndex(nums, 88)); // 3
    }

    public static int queryIndex(int[] arr, int num) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == num) return i;
        }
        return -1;
    }
}

3.比较数组是否相同

需求:

  • 要求传入两个整形数组, 如果两个数组, 元素个数,元素顺序和内容是一样的我们就认为这2个数组是一模一样的。
  • 请使用方法完成:能够判断任意两个整型数组是否一样,并返回true或者false。

分析:

  • 定义方法,接收2个整型数组,—> 是否需要参数、返回值类型?
  • 在方法内部完成判断的逻辑,并返回布尔结果。
public class methodDemo05 {
    public static void main(String[] args) {
        int[] arr1 = {10, 20, 30};
        int[] arr2 = {10, 20, 30};
        int[] arr3 = {10, 20, 99};

        System.out.println(compare(arr1, arr2)); // true
        System.out.println(compare(arr1, arr3)); // false
    }

    public static boolean compare(int[] arr1, int[] arr2) {
        if (arr1.length != arr2.length) return false;
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) return false;
        }
        return true;
    }
}

方法重载

方法重载: 同一个类中,出现多个方法名称相同,但是形参列表是不同的,那么这些方法就是重载方法

我们结合案例来理解一下方法重载 :

例如开发武器系统,功能需求如下

  • 可以默认发一枚武器。
  • 可以指定地区发射一枚武器。
  • 可以指定地区发射多枚武器。

示例代码 :

// 1.默认给岛国发射一枚导弹
public static void fire() {
    System.out.println("给岛国的随机地区发射1枚导弹给岛国");
}

// 2.给岛国指定地区发射一枚导弹
public static void fire(String address) {
    System.out.println("给岛国的" + address + "地区发射1枚导弹");
}

// 3.给岛国指定地区发射自定义枚导弹
public static void fire(String address, int num) {
    System.out.println("给岛国的" + address + "地区发射" + num + "枚导弹");
}

调用方法的时候, 会通过参数的不同来区分调用的是哪个方法

public static void main(String[] args) {
    fire();
    fire("东京");
    fire("东京", 9999);
}

方法重载还有另一种使用方法: 效果一样的, 代码更简洁

public static void main(String[] args) {
    fire();
    fire("东京");
    fire("东京", 9999);
}

// 1.默认给岛国发射一枚导弹
public static void fire() {
  	// 可以方法中调用方法, 效果一样使代码更简洁
    fire("随机");
}

// 2.给岛国指定地区发射一枚导弹
public static void fire(String address) {
    fire(address, 1);
}

// 3.给岛国指定地区发射自定义枚导弹
public static void fire(String address, int num) {
    System.out.println("给岛国的" + address + "地区发射" + num + "枚导弹");
}

方法重载的好处: 对于相似功能的业务场景:可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。

方法重载的识别:

  • 只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管!(如:修饰符,返回值类型都无所谓)

  • 形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称

return的单独使用

return关键字单独使用

  • return; —> 可以立即跳出并结束当前方法的执行; return关键字单独使用可以放在任何方法中
public class Test {
		public static void main(String[] args) {
        System.out.println("开始");
    		chu(10 , 0);
        System.out.println("结束");
  	}
  	public static void chu(int a , int b){
    		if(b == 0){
      			System.err.println("您的数据有误!!不执行!!");
      			return; // 直接结束当前方法chu
    		}
    int c = a / b;
				System.out.println("除法结果是:"+c);
		}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/120100.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!