当前位置: 首页 > article >正文

【JavaSE】--方法的使用

文章目录

  • 1. 方法概念及使用
    • 1.1 什么是方法
    • 1.2 方法定义
    • 1.3 方法调用的执行过程
    • 1.4 实参和形参的关系(重要)
    • 1.5 没有返回值的方法
  • 2. 方法重载
    • 2.1 方法重载概念
    • 2.2 方法签名
  • 3. 递归
    • 3.1 递归的概念
    • 3.2 递归执行过程分析
    • 3.3 递归练习

1. 方法概念及使用


1.1 什么是方法

方法就是一个代码片段. 类似于 C 语言中的 “函数”。方法存在的意义(不要背, 重在体会):

  1. 是能够模块化的组织代码(当代码规模比较复杂的时候).
  2. 做到代码被重复使用, 一份代码可以在多个位置使用.
  3. 让代码更好理解更简单.
  4. 直接调用现有方法开发, 不必重复造轮子.

1.2 方法定义

方法语法格式:在这里插入图片描述

注意事项:

  1. 修饰符:现阶段直接使用public static 固定搭配
  2. 返回值类型:如果方法有返回值,返回值类型必须要与返回的实体类型一致,如果没有返回值,必须写成void。
  3. 方法名字:采用小驼峰命名
  4. 参数列表:如果方法没有参数,()中什么都不写,如果有参数,需指定参数类型,多个参数之间使用逗号隔开。
  5. 方法体:方法内部要执行的语句。
  6. 在java当中,方法必须写在类当中
  7. 在java当中,方法不能嵌套定义。
  8. 在java当中,没有方法声明一说。

1.3 方法调用的执行过程

【方法调用过程】
调用方法—>传递参数—>找到方法地址—>执行被调方法的方法体—>被调方法结束返回—>回到主调方法继续往下执行.

【注意事项】

  • 定义方法的时候, 不会执行方法的代码. 只有调用的时候才会执行.
  • 一个方法可以被多次调用.

1.4 实参和形参的关系(重要)

代码示例:

public static boolean func(int year){
        year = 100;
    }
public static void main(String[] args) {
    int year = 2008;
    func(year);
    System.out.println(year);
}

所有方法在调用的时候,要在栈上开辟内存,叫做栈帧。程序开始调用main方法,会在栈上开辟一块内存,来作为main()方法的栈帧. 在调用 func() 方法时,也会在栈上开辟一块内存来作为 func() 的栈帧。

此时在main方法中的year的值是2008,在 func() 方法调用的时候,我们将main()方法中year中的值给到了 func() 中的year, 此时 func() 方法中的值也是2008。

但是我们在 func() 中修改year的值,不会影响main方法中year的值,我们在 func() 中修改的只是形参的值,当 func() 这个方法执行完就会将这个方法的栈帧销毁掉。此时程序回到main方法打印year的值,此时打印出来的还是2008.

这个例子说明了形参值的改变不会影响实参的值。

Java当中是拿不到栈上的地址的。

在Java中,实参的值永远都是拷贝到实参中的(传值调用),形参和实参本质上是两个实体。

解决方法: 传引用类型参数(例如数组).

1.5 没有返回值的方法

方法的返回值是可选的. 有些时候可以没有,没有时返回值类型必须写成void.

2. 方法重载


2.1 方法重载概念

在Java中,如果多个方法的名字相同,参数列表不同,则称该几种方法被重载了。

public class TestMethod {
    public static void main(String[] args) {
        add(1, 2); // 调用add(int, int)
        add(1.5, 2.5); // 调用add(double, double)
        add(1.5, 2.5, 3.5); // 调用add(double, double, double)
    }
    public static int add(int x, int y) {
        return x + y;
    }
    public static double add(double x, double y) {
        return x + y;
    }
    public static double add(double x, double y, double z) {
        return x + y + z;
    }
}

注意:

  1. 方法名必须相同
  2. 参数列表必须不同(参数的个数不同、参数的类型不同、类型的次序三者必须有一个不同)
  3. 与返回值类型是否相同无关.
// 注意:两个方法如果仅仅只是因为返回值类型不同,是不能构成重载的
public class TestMethod {
     public static void main(String[] args) {
         int a = 10;
         int b = 20;
         int ret = add(a, b);
         System.out.println("ret = " + ret);
     }
     public static int add(int x, int y) {
         return x + y;
     }
     public static double add(int x, int y) {
         return x + y;
     }
 }
// 编译出错
// Test.java:13: 错误: 已在类 Test中定义了方法 add(int,int)
// public static double add(int x, int y) {
//        ^
//     1 个错误

  1. 编译器在编译代码时,会对实参类型进行推演,根据推演的结果来确定调用哪个方法.

判断是否构成重载,我们只看前两条是否满足。

2.2 方法签名

在同一个作用域中不能定义两个相同名称的标识符。比如:方法中不能定义两个名字一样的变量,那为什么类中就可以定义方法名相同的方法呢?
方法签名即:经过编译器编译修改过之后方法最终的名字。具体方式:方法全路径名+参数列表+返回值类型,构成方法完整的名字。

public class TestMethod {
       public static int add(int x, int y){
           return x + y;
       }
       public static double add(double x, double y){
           return x + y;
       }
       public static void main(String[] args) {
           add(1,2);
           add(1.5, 2.5);
       }
   }

上述代码经过编译之后,然后使用JDK自带的javap反汇编工具查看,具体操作:

  1. 先对工程进行编译生成.class字节码文件
  2. 在控制台中进入到要查看的.class所在的目录
  3. 输入:javap -v 字节码文件名字即可
    在这里插入图片描述

3. 递归


3.1 递归的概念

一个方法在执行过程中调用自身, 就称为 “递归”.

解决递归问题:

  1. 推出一个递推公式(难)。
  2. 找到当前问题的递归“结束条件”(起始条件)。
    注意: 考虑怎么“递” 考虑怎么“归”------要有"递" 有 “归”.

3.2 递归执行过程分析

递归求 N 的阶乘

在这里插入图片描述
关于 “调用栈”
方法调用的时候, 会有一个 “栈” 这样的内存空间描述当前的调用关系. 称为调用栈.
每一次的方法调用就称为一个 “栈帧”, 每个栈帧中包含了这次调用的参数是哪些, 返回到哪里继续执行等信息.

3.3 递归练习

代码示例1 按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)

public static void print(int num) {
    if (num > 9) {
        print(num / 10);
    }
    System.out.println(num % 10);
}

代码示例2 递归求 1 + 2 + 3 + … + 10

public static int sum(int num) {
    if (num == 1) {
        return 1;
    }
    return num + sum(num - 1);
}

代码示例3 写一个递归方法,输入一个非负整数,返回组成它的数字之和. 例如,输入 1729, 则应该返回1+7+2+9,它的和是19

public static int sum(int num) {
    if (num < 10) {
        return num;
    }
    return num % 10 + sum(num / 10);
}

代码示例4 求斐波那契数列的第 N 项

public static int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return fib(n - 1) + fib(n - 2);
}

当我们求 fib(40) 的时候发现, 程序执行速度极慢. 原因是进行了大量的重复运算.
可以使用循环的方式来求斐波那契数列问题, 避免出现冗余运算。

public static int fib(int n) {
    int last2 = 1;
    int last1 = 1;
    int cur = 0;
    for (int i = 3; i <= n; i++) {
        cur = last1 + last2;
        last2 = last1;
        last1 = cur;
    }
    return cur;
}

此时程序的执行效率大大提高了.


http://www.kler.cn/a/303110.html

相关文章:

  • IPguard与Ping32全面对比——选择最适合企业的数据安全解决方案
  • 【Mode Management】AUTOSAR架构下唤醒源检测函数EcuM_CheckWakeup详解
  • TDesign了解及使用
  • LeetCode【0014】最长公共前缀
  • JUC-locks锁
  • Oracle OCP认证考试考点详解082系列16
  • 【vuetify】v-select 无法正常显示,踩坑记录!
  • 京东鸿蒙上线前瞻——使用 Taro 打造高性能原生应用
  • .net core 通过Sqlsugar生成实体
  • 安全政策与安全意识(下)
  • 【2024】前端学习笔记3-外部链接-内部链接-锚点链接
  • 鱼类检测-目标检测数据集(包括VOC格式、YOLO格式)
  • mariadb主从配置步骤
  • 苹果CMS影视程序被举报侵权?有效解决方案指南
  • 从 Greenplum 到 Databend,数据仓库的开源新选择
  • 自定义WPF滑块样式-Slider
  • 桥接模式详解和分析JDBC中的应用
  • 微信小程序开发——比较两个数字大小
  • JavaScript知识点2
  • 告别繁琐,IsMyHdOK硬盘测速,即刻享受科技便利
  • 安全工具 | 使用Burp Suite的10个小tips
  • Apache SeaTunnel Committer 进阶指南
  • 数据结构和算法之基本概念
  • Azure web app has no access to openai private endpoint in virtual network
  • 4G物联网智能电表是什么?什么叫4G物联网智能电表?
  • 参数传了报错没传参数识别不到参数传丢