Java 方法(方法的调用机制、方法的传参机制)

方法

方法就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。 当需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象。

修饰符 返回值类型 方法名 (参数列表){ 
    代码... 
    return 返回值;

定义格式解释:

  • 修饰符: 用于控制方法使用的范围,权限修饰符、静态修饰符、final修饰符 。
  • 返回值类型:表示方法运行的结果的数据类型,方法执行后将结果返回到调用者。一个方法只能有一个返回值。void表示没有返回值。
  • 方法名:为我们定义的方法起名,满足标识符的规范,用来调用方法。
  • 参数列表: 方法在运算过程中的未知数据,调用者调用方法时传递。可以没有参数,也可以有多个参数,用逗号隔开。参数类型可以为任意类型,可以使用基本类型和引用类型。当调用该方法时,传入的参数要与参数列表顺序相同或者兼容的类型的参数。
  • return:将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束。如果没有返回值,该语句不是必须的,但是也可以写return,当代码执行到的时候,表示方法结束。

方法必须定义在一类中方法外,不能定义在另一个方法的里面,定义方法需明确返回值类型和参数列表,返回值类型,必须要和 return 语句返回的类型相同,否则编译失败。不能在 return 后面写代码, return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码。

方法定义时的参数叫形参,方法调用时的参数叫实参,实参和形参的类型要一直或兼容,个数、顺序必须一致。

方法不能嵌套定义!!

同一个类中的方法可以直接调用,跨类调用需要通过对象名调用,比如对象名.方法名(参数);,方法的调用还和访问修饰符相关。

public class Method01 {
    public static void main(String[] args) {
        // 方法的使用
        // 定义好方法后,如果不调用,则不会执行
        // 先创建对象,然后进行调用
        Person p1 = new Person();
        p1.speak(); // 这里调用方法
        p1.cal01();
        p1.cal02(1000); // 传入的是1000,则n=1000
        p1.cal02(5); // 一个对象的方法可以调用多次

        // 将该方法返回的int值 赋值给 sum 变量
        int sum = p1.getSum(10, 20); // 传参是10,20,则n = 10, m = 20,使用int sum来接收方法的返回值
        System.out.println("getSum方法得到的返回值为:" + sum);
    }
}

class Person {
    String name;
    int age;

    // 方法(成员方法)
    // 输出“我是一个好人”
    // public:表示方法是公开的
    // void:表示方法没有返回值
    // speak:方法名
    // ():形参列表
    // {}:方法体,就是要执行的代码
    public void speak() {
        System.out.println("我是一个好人");
    }

    // 计算1+...+100
    public void cal01() {
        // 进行循环
        int res = 0;
        for (int i = 1; i <= 100; i++) {
            res += i;
        }
        System.out.println("cal01计算结果:" + res);
    }

    // 计算1+...+n
    // (int n):形参列表,表示当前方法可以传入一个int的值
    public void cal02(int n) {
        int res = 0;
        for (int i = 1; i <= n; i++) {
            res += i;
        }
        System.out.println("cal02计算结果:" + res);
    }

    // 计算两个数的和,并返回
    // public后面的int:表示方法执行后,返回给调用者一个int的值
    // (int n, int m):有两个形参,表示当前方法可以接收两个参数
    // return res;:表示把res的值返回给调用者
    public int getSum(int n, int m) {
        int res = m + n;
        return res;
    }
}

方法的调用机制

(参考上面代码)

image

  1. 当程序执行到方法时,就会开辟出一个独立的空间(栈空间)
  2. 当方法执行完毕,或者执行到return语句时,就会返回
  3. 返回到调用的地方
  4. 返回后继续执行方法后面的代码
  5. 当main方法执行完毕后,程序就退出了

方法的传参机制

public class MethodParameter01 {
    //编写一个 main 方法
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        //创建 AA 对象 名字obj 
        AA obj = new AA();
        obj.swap(a, b);//调用 swap
        System.out.println("\nmain 方法 a=" + a + " b=" + b);//a=10 b=20
    }
}

class AA {
    public void swap(int a, int b) {
        System.out.println("\na 和 b 交换前的值\na=" + a + "\tb=" + b);//a=10 b=20 
        // 完成了 a 和 b 的交换 
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("\na 和 b 交换后的值\na=" + a + "\tb=" + b);//a=20 b=10 
    }
}

基本数据类型传递的是值(值拷贝),形参的任何改变不影响实参

当执行obj.swap(a, b);的时候会进入swap方法中,在该方法中,该方法的参数a和b完成了值的交换,但是main方法中的a和b并没有交换,所以输出如下:

image

image


public class MethodParameter02 {
    //编写一个 main 方法
    public static void main(String[] args) {
        B b = new B();
        int[] arr = {1, 2, 3};
        b.test(arr);  //调用方法
        System.out.println(" main 的 arr 数组 ");

        //遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
    }
}

class B {
    public void test(int[] arr) {
        arr[0] = 200;   //修改元素 
        // 遍历数组 
        System.out.println(" test100 的 arr 数组 ");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
    }
}

引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参!

image

方法​重载

java 中允许同一个类中,多个同名方法的存在,但要求形参列表不一致。只要它们的参数列表不同即可,与修饰符和返回值类型无关。 比如:System.out.println(); out 是 PrintStream 类型。

  • 参数列表: 个数不同,数据类型不同,顺序不同。如果参数列表类型、顺序、数量相同,参数名不同,不构成重载。
  • 返回类型:如果参数列表相同,方法名相同,返回值不同,不构成重载。
  • 重载方法调用: JVM通过方法的参数列表,调用不同的方法。
public class OverLoad01 {
    public static void main(String[] args) {
        MyCalculate mc = new MyCalculate();
        System.out.println(mc.calculate(1, 2));        // 打印结果:3
        System.out.println(mc.calculate(3, 4.5));    // 打印结果:7.5
        System.out.println(mc.calculate(1.2, 2));    // 打印结果:3.2
        System.out.println(mc.calculate(1, 4, 7));    // 打印结果:12
    }
}

// 这个类的四个calculate方法构成了重载
// 方法名一样,参数列表的类型不一样
class MyCalculate {
    // 两个整数的和
    public int calculate(int n1, int n2) {
        return n1 + n2;
    }

    // 这个方法和上面的方法不构成重载,因为参数列表的类型相同
//    public int calculate(int a1, int a2) {
//        return a1 + a2;
//    }

    // 一个整数和一个浮点数的和
    public double calculate(int n1, double n2) {
        return n1 + n2;
    }

    // 一个浮点数和一个整数的和
    public double calculate(double n1, int n2) {
        return n1 + n2;
    }

    // 三个整数的和
    public int calculate(int n1, int n2, int n3) {
        return n1 + n2 + n3;
    }
}

可变参数

Java允许将同一个类 多个同名 同功能参数个数不同的方法,封装成一个方法。在JDK1.5之后,如果定义一个方法需要接收多个参数,并且多个参数类型一致,可以对其简化成如下格式:

修饰符 返回值类型 方法名(参数类型... 形参名){ }
public class ChangeParam01 {
    // 计算两个数的和,三个数的和,四个数的和,五个数的和....
    // 可以使用方法重载
    public int sum(int n1, int n2) {return n1 + n2;}
    public int sum(int n1, int n2, int n3) {return n1 + n2 + n3;}
    public int sum(int n1, int n2, int n3, int n4) {return n1 + n2 + n3 + n4;}

    // 上面三个方法名称相同,功能相同,只有参数个数不同,可以使用可变参数优化
    // int... 表示该参数是可变参数,类型是int,可以接收多个int类型的参数(0-n个参数)
    public int sums(int... nums) {
        // 使用可变参数时,可以当做数组使用,所以nums是一个数组
        System.out.println("接收的参数个数为:" + nums.length);
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }

    public static void main(String[] args) {
        ChangeParam01 cp = new ChangeParam01();
        int res = cp.sums(0, 1, 2, 3, 4, 5, 6, 7);
        System.out.println("返回的结果为:" + res);

        int[] arr = {3, 6, 9};
        // 可变参数的实参可以传入数组
        int res2 = cp.sums(arr);
        System.out.println("res2的结果:" + res2);
    }
}
  • 使用可变参数时,参数可以当做数组使用,同样是数组,但是在调用这个带有可变参数的方法时,不用创建数组,直接将多个相同类型的元素作为实际参数进行传递。
  • 在jvm编译成class文件时,会将这些元素封装到一个数组中,然后再进行传递。这些动作都在编译.class文件时,自动完成了。
  • 可变参数的实参可以为数组。
  • 可变参数可以和普通类型的参数放在形参列表,但必须保证可变参数在最后。
    • 例如:public void sums(String str, double... nums) {}
  • 一个形参列表中只能出现一个可变参数

作用域

在Java中,主要的变量就是成员变量和局部变量。

在同一个类中,成员变量和局部变量可以重名,访问时遵循就近原则;但是在同一个作用域中,比如在同一个成员方法中,两个局部变量不能重名。

默认值:

  • **成员变量:**有默认值,可以直接使用。
  • **局部变量:**没有默认值,需要先赋值后使用。

生命周期:

  • **成员变量:**生命周期较长,伴随着对象的创建而创建,随着对象的销毁而销毁。
  • **局部变量:**生命周期较短,伴随着他的代码块的执行而创建,随着代码块的结束而销毁(就是在一次方法的调用中开始,方法结束,变量随之销毁)。

作用域:

  • **成员变量:**作用域为整个类,可以本类使用,或者其他类使用(通过对象调用)。
  • **局部变量:**只能在本类中应对的方法(代码块)中使用。

修饰符:

  • **成员变量:**可以加修饰符。
  • **局部变量:**不可以加修饰符。

构造方法

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。

[修饰符] 方法名(形参列表){
    方法体;
}
  • 构造器的修饰符可以默认,也可以是 public protected private
  • 构造器没有返回值,也不需要void
  • 方法名和类名字必须相同
  • 参数列表 和 成员方法一样的规则,既可以定义参数,也可以不定义参数
  • 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化。
  • 构造器是完成对象的初始化,并不是创建对象
  • 一个类可以定义多个不同构造器,是可以重载的。
  • 如果没有定义构造器,系统会自动给出一个默认无参的构造器,也叫做默认构造器
  • 如果定义了构造器,默认的构造器会被覆盖,除非手动创建一个无参构造
package object;

public class Constructor {
    public static void main(String[] args) {
        // 使用两种不同的构造器
        Person p = new Person("张三", 25);
        System.out.println("name:" + p.name);
        System.out.println("age:" + p.age);

        Person p1 = new Person("李四");
        System.out.println("name:" + p1.name);
        System.out.println("age:" + p1.age);
    }
}

class Person {

    String name;
    int age;

    // 构造器没有返回值,也不需要写void
    // 构造方法的方法名必须和类名一样
    // 形参列表和其他方法一样
    public Person(String pName, int pAge) {
        System.out.println("构造器执行了....");
        name = pName;
        age = pAge;
        System.out.println("构造器完成了对属性的初始化...");
    }

    // 构造器可以重载
    public Person(String pName) {
        name = pName;
    }

    // 如果我们定义了构造器,则默认构造器会被覆盖,如果需要,可以手动创建无参构造
    // 默认的无参构造访问修饰符也是默认的
    public Person() {

    }
}

可以使用javap工具反编译,能看到反编译后的结果中有定了一个 访问修饰符为默认 方法名为类名的方法。

image

对象创建的流程

class Person {
    String name;
    int age = 90;

    // 构造器
    Person(String n, int a) {
        name = n;
        age = a;
    }
}

// 对象创建时发生了什么
Person p = new Person("张三", 20);

image

  1. 加载Person类信息(Person.class),只会加载一次,不会重复加载
  2. 在堆中分配空间(地址)
  3. 完成对象的初始化(默认初始化 age = 0 → 显式初始化 age = 90 → 构造器初始化 age = 20)
  4. 把对象在堆中的地址赋值给p(对象名)

this关键字

Java虚拟机会给每个对象分配this, 代表所在类的当前对象的引用(地址值),即对象自己的引用。方法被哪个对象调用,方法中的this就代表那个对象。即谁在调用,this就代表谁,方法中只有一个变量名时,默认也是使用 this 修饰,可以省略不写。

class Dog {
    String name;
    int age;

    // 不使用this,name则等于该方法中的name(就近原则)
//    public Dog(String name, int age){
//        name = name;
//        age = age;
//    }

    // 使用this 相当于是Dog对象.name,指的是Dog类中的属性,而没有加this的name指的是方法中的name
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

image

  • this关键字可以访问本类的属性、方法、构造器

  • this用于区分当前类的属性和局部变量

  • 访问成员方法的语法:this.方法名(参数列表);

  • 访问构造器语法:this(参数列表);,只能在构造器中使用(并且必须放在第一行)

  • this不能再类定义的外部使用,只能在类定义的方法中使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/333636.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CC工具箱使用指南:【计算面积】

一、简介 在Arcgis中&#xff0c;如果要计算面要素的面积&#xff0c;有几种方法。 1、gdb数据会自带一个shape_area字段&#xff0c;这就是面的平面面积&#xff0c;单位是平方米&#xff1a; 2、在双精度字段上右键单击&#xff0c;在弹出的菜单中点击【计算几何】&#xf…

制造业企业数字化转型难点剖析及解决之法

导语 全球正在由工业经济向数字经济转型过渡&#xff0c;制造业正在且并将长期处于数字化转型发展阶段&#xff0c;并沿着数字化、网络化、智能化阶段不断跃升。但如何找准数字化转型的切入点&#xff0c;以低耗能、低成本、高效率的方式加快制造业转型升级的步伐&#xff0c;仍…

普兰资产(PLAN B KRYPTO ASSETS):Schutz AI 公链引领数字资产新时代

比特B ETF是金融技术革命的起始 普兰资产&#xff08;PLAN B KRYPTO ASSETS&#xff09;执行长Jonah Fischer指出&#xff0c;比特B ETF 仅是迈向金融领域技术革命的首个阶段。他认为比特B现货 ETF 提供了投资者接触年轻且具有风险性的资产的途径&#xff0c;但他强调区块链技术…

Linux自动化构建工具——make和Makefile使用详解

一、初步认识make和Makefile 我们首先需要知道的是&#xff0c;make是一个命令&#xff0c;Makefile是一个文件&#xff0c;Makefile中包含了依赖关系和依赖方法。 从上面的文件以及指令中我们可以看到&#xff0c;我们可以在Makefile文件中写入依赖关系以及对应的依赖方法&…

2024执业医师考试报名流程及上传照片要求详解

2024年执业医师和助理医师考试的报名工作将于1月22日正式启动&#xff0c;报名截止日期为2月4日。建议考生尽早报名&#xff0c;以避免在报名截止日期临近时出现拥挤情况。您可根据本文介绍&#xff0c;提前准备好报名所需资料、证件照电子版和相关证明材料&#xff0c;并了解报…

【我与Java的成长记】之多态,重载与重写详解

系列文章目录 能看懂文字就能明白系列 C语言笔记传送门 Java笔记传送门 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言一、多态的概…

米贸搜|Facebook新手请查收!如何在FB上定位到B类受众?

一、确定目标受众和营销目标 在利用Facebook进行获客之前&#xff0c;B2B企业需要首先明确目标受众和营销目标。目标受众是指潜在的客户或合作伙伴&#xff0c;而营销目标可能是增加销量、提高品牌知名度、获取客户线索等。 Facebook的受众定位可以分成三大类&#xff1a;人口…

Netty通信中的粘包半包问题(五)

这期我们来分析下消息头消息体的这种方式来实现完美的解决方案&#xff0c;当然这也是最复杂的一种实现&#xff0c;因为在大多数场景中&#xff0c;性能和复杂度始终不能兼得。代码中使用了MessagePack的第三方序列化&#xff0c;因为我们要传输的实体类对象在客户端和服务端之…

从matlab的fig图像文件中提取数据

这里用的是openfig&#xff08;&#xff09;函数打开的fig文件 →→→【matlab 中 fig 数据提取】 很简洁 →→→【MATLAB提取 .fig 文件中的数据】 这个给出了包含多个曲线的情况 →→→【提取matlab fig文件里的数据和legend】 chatgpt给出的方法 打开fig文件并保存数据 我的…

Git 基本命令与操作流

记录 Git 中的基本命令和创建仓库、提交文件、删除文件等方面的操作 Git 基本命令 git status&#xff1a;查看状态 nothing to commit, working directory clean&#xff1a;所有已跟踪文件在上次提交后都未被更改过&#xff0c;或者说当前目录下没有出现任何处于未跟踪状态…

Java 类与对象(对象的分配机制、对象的创建过程、匿名对象)

面向对象 面向对象编程&#xff08;Object-Oriented Programming 简称 OOP&#xff09;是一种程序设计思想和编码架构。 Java 是完全面向对象的&#xff0c; 必须熟悉 OOP 才能够编写 Java 程序。 面向对象的程序是由对象组成的&#xff0c;每个对象包含对用户公开的特定功能…

基于springboot+vue的蜗牛兼职网的设计与实现系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

力扣每日一练(24-1-18)

经验一&#xff1a;不要把问题想复杂 Python&#xff1a; min_price float(inf)max_profit 0for price in prices:min_price min(min_price, price)max_profit max(max_profit, price - min_price)return max_profit C#&#xff1a; public int MaxProfit(int[] prices) {i…

GNU Radio简介及流程图搭建

文章目录 前言一、GNU Radio 是什么&#xff1f;二、GNU Radio 安装三、搭建第一个流程图1、创建 GRC 文件2、添加块3、运行流程图 前言 欢迎来到无线通信的世界&#xff0c;初步接触 GNU Radio&#xff0c;对其学习进行一个记录。 一、GNU Radio 是什么&#xff1f; GNU Rad…

【重点!!!】【背包】【回溯】518.零钱兑换II

题目 跟39.组合总数、322.零钱兑换题目很类似。 法1&#xff1a;背包DP&#xff0c;最优解法 解释如下&#xff1a; 0 1 2 3 4 5(背包容量)1 0 0 0 0 0 没有硬币的时候&#xff09; 0 1 2 3 4 5(背包容量) 1 1 1 1 1 1 1 0 1 2 3 4 5(背包容量) 1 …

深入解析 Java 方法引用:Lambda 表达式的进化之路

前言 方法引用是 Java 8 提供的一种新特性&#xff0c;它允许我们更简洁地传递现有方法作为参数。这项特性实际上是对 Lambda 表达式的一种补充&#xff0c;通过方法引用&#xff0c;我们可以直接引用现有方法&#xff0c;而无需编写完整的Lambda表达式。最近在使用方法引用的…

Spring(19) ThreadPoolTaskExecutor 线程池的使用

目录 一、线程池简介1.1 为什么使用线程池1.2 线程池为什么需要使用队列1.3 线程池为什么要使用阻塞队列而不是用非阻塞队列1.4 如何配置线程池1.5 execute() 和 submit() 方法 二、ThreadPoolTaskExecutor 线程池简介2.1 简介2.2 核心参数配置2.3 ThreadPoolTaskExecutor 内部…

TortoiseSVN客户端如何安装配置并实现公网访问服务端提交文件到本地服务器

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统&#xff0c;它与Apache Subversion&#xff08;SVN&#xff09;集成在一起&#xff0c;提供了一个用户友好的界面&#xff0c;方便用…

CSV文件中json列的处理2

如上所示&#xff0c;csv文件中包含以中括号{}包含的json字段&#xff0c;可用如下方法提取&#xff1a; import pandas as pd from datetime import date todaystr(date.today()) import jsonfilepath/Users/kangyongqing/Documents/kangyq/202401/调课功能使用统计/ file104…

顶顶通呼叫中心中间件如何实现自己呼叫自己并且放音:一步步配置(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件如何实现自己呼叫自己并且放音&#xff1a;一步步配置 一、配置acl.conf 打开ccadmin-》点击配置文件并且打开acl.conf-》配置好了点击提交XML。 注意&#xff1a;acl.conf的服务器IP必须是内网IP 添加了之后在运维调试输入reloadacl 在运维调试执…