Java - 方法 Method

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

方法的概念

方法也叫函数,是一组代码语句的封装,从而实现代码重用,从而减少冗余代码,通常它是一个独立功能的定义,方法是一个类中最基本的功能单元

Math.random()的random()方法
Math.sqrt(x)的sqrt(x)方法
System.out.println(x)的 println(x)方法

Scanner input = new Scanner(System.in);
input.nextInt()的nextInt()方法
复制代码

方法的特点

必须先声明后使用

类,变量,方法等都要先声明后使用

不调用不执行,调用一次执行一次

如何声明方法

声明方法的位置

声明方法的位置必须在类中方法外,即不能在一个方法中直接定义另一个方法

类{
    方法1(){
        
    }
    方法2(){
        
    }
}
复制代码

错误示例

类{
    方法1(){
        方法2(){  //位置错误
        
   		}
    }
}
复制代码

声明方法的语法格式

【修饰符】 返回值类型 方法名(【形参列表 】)【throws 异常列表】{
        方法体的功能代码
}
复制代码
修饰符
  • 可选的,方法的修饰符也有很多,例如:public、protected、private、static、abstract、native、final、synchronized 等

  • 其中根据是否有 static,可以将方法分为静态方法和非静态方法

  • 其中静态方法又称为类方法,非静态方法又称为实例方法

返回值类型

表示方法运行的结果的数据类型,方法执行后将结果返回到调用者

  • 基本数据类型

  • 引用数据类型

  • 无返回值类型:void

参数列表

表示完成方法体功能时需要外部提供的数据列表

  • 无论是否有参数,()不能省略
  • 如果有参数,每一个参数都要指定数据类型和参数名,多个参数之间使用逗号分隔
    • 一个参数: (long num)
    • 二个参数: (int num, long sum)
  • 参数的类型可以是基本数据类型、引用数据类型

  • throws 异常列表:可选

关于方法体中return语句的说明
  • return 语句的作用是结束方法的执行,并将方法的结果返回去

  • 如果返回值类型不是 void,方法体中必须保证一定有return 返回值;语句,并且要求该返回值结果的类型与声明的返回值类型一致或兼容

  • 如果返回值类型为 void 时,方法体中可以没有 return 语句,如果要用 return 语句提前结束方法的执行,那么r eturn 后面不能跟返回值,直接写return ;就可以

  • return 语句后面就不能再写其他代码了,否则会报错:Unreachable code

案例

package com.test04.method;

/**
 * 方法定义案例演示
 */
public class MethodDefineDemo {
    /**
     * 无参无返回值方法的演示
     */
    void sayHello(){
        System.out.println("hello");
    }

    /**
     * 有参无返回值方法的演示
     * @param length int 第一个参数,表示矩形的长
     * @param width int 第二个参数,表示矩形的宽
     * @param sign char 第三个参数,表示填充矩形图形的符号
     */
    void printRectangle(int length, int width, char sign){
        for (int i = 1; i <= length ; i++) {
            for(int j=1; j <= width; j++){
                System.out.print(sign);
            }
            System.out.println();
        }
    }

    /**
     * 无参有返回值方法的演示
     * @return
     */
    int getIntBetweenOneToHundred(){
        return (int)(Math.random()*100+1);
    }
    
    /**
     * 有参有返回值方法的演示
     * @param a int 第一个参数,要比较大小的整数之一
     * @param b int 第二个参数,要比较大小的整数之二
     * @return int 比较大小的两个整数中较大者的值
     */
    int max(int a, int b){
        return a > b ? a : b;
    }
}
复制代码

如何调用实例方法

方法调用语法格式

对象.非静态方法(【实参列表】)
复制代码

案例

package com.atguigu.test04.method;

/**
 * 方法调用案例演示
 */
public class MethodInvokeDemo {
    public static void main(String[] args) {
        //创建对象
        MethodDefineDemo md = new MethodDefineDemo();

        System.out.println("-----------------------方法调用演示-------------------------");

        //调用MethodDefineDemo类中无参无返回值的方法sayHello
        md.sayHello();
        md.sayHello();
        md.sayHello();
        //调用一次,执行一次,不调用不执行

        System.out.println("------------------------------------------------");
        //调用MethodDefineDemo类中有参无返回值的方法printRectangle
        md.printRectangle(5,10,'@');

        System.out.println("------------------------------------------------");
        //调用MethodDefineDemo类中无参有返回值的方法getIntBetweenOneToHundred
        md.getIntBetweenOneToHundred();//语法没问题,就是结果丢失

        int num = md.getIntBetweenOneToHundred();
        System.out.println("num = " + num);

        System.out.println(md.getIntBetweenOneToHundred());
        //上面的代码调用了getIntBetweenOneToHundred三次,这个方法执行了三次

        System.out.println("------------------------------------------------");
        //调用MethodDefineDemo类中有参有返回值的方法max
        md.max(3,6);//语法没问题,就是结果丢失
        
        int bigger = md.max(5,6);
        System.out.println("bigger = " + bigger);

        System.out.println("8,3中较大者是:" + md.max(8,9));
    }
}
复制代码

形参和实参

  • 形参(formal parameter):在定义方法时方法名后面括号中声明的变量称为形式参数(简称形参)即形参出现在方法定义时。

  • 实参(actual parameter):调用方法时方法名后面括号中的使用的值/变量/表达式称为实际参数(简称实参)即实参出现在方法调用时。

  • 调用时,实参的个数、类型、顺序顺序要与形参列表一一对应。如果方法没有形参,就不需要也不能传实参。

  • 无论是否有参数,声明方法和调用方法是==()都不能丢失==

返回值问题

方法调用表达式是一个特殊的表达式

  • 如果被调用方法的返回值类型是 void,调用时不需要也不能接收和处理(打印或参与计算)返回值结果,即方法调用表达式只能直接加;成为一个独立语句
  • 如果被调用方法有返回值,即返回值类型不是 void
    • 方法调用表达式的结果可以作为赋值表达式的值
    • 方法调用表达式的结果可以作为计算表达式的一个操作数
    • 方法调用表达式的结果可以作为另一次方法调用的实参
    • 方法调用表达式的结果可以不接收和处理,方法调用表达式直接加;成为一个独立的语句,这种情况,返回值丢失
package com.atguigu.test04.method;

public class MethodReturnValue {
    public static void main(String[] args) {
        //创建对象
        MethodDefineDemo md = new MethodDefineDemo();

        //无返回值的都只能单独加;成一个独立语句
        //调用MethodDefineDemo类中无参无返回值的方法sayHello
        md.sayHello();
        //调用MethodDefineDemo类中有参无返回值的方法printRectangle
        md.printRectangle(5,10,'@');

        //有返回值的
        //(1)方法调用表达式可以作为赋值表达式的值
        int bigger = md.max(7,3);
        System.out.println("bigger = " + bigger);

        //(2)方法调用表达式可以作为计算表达式的一个操作数
        //随机产生两个[1,100]之间的整数,并求和
        int sum = md.getIntBetweenOneToHundred() + md.getIntBetweenOneToHundred();
        System.out.println("sum = " + sum);

        //(3)方法调用表达式可以作为另一次方法调用的实参
        int x = 4;
        int y = 5;
        int z = 2;
        int biggest = md.max(md.max(x,y),z);
        System.out.println("biggest = " + biggest);

        //(4)方法调用表达式直接加;成为一个独立的语句,这种情况,返回值丢失
        md.getIntBetweenOneToHundred();
    }
}
复制代码

实例方法使用当前对象的成员

在实例方法中还可以使用当前对象的其他成员。在Java中当前对象用this表示。

  • this:在实例方法中,表示调用该方法的对象
  • 如果没有歧义,完全可以省略this

使用this.

案例:矩形类

package com.atguigu.test04.method;

public class Rectangle {
    int length;
    int width;

    int area() {
        return this.length * this.width;
    }

    int perimeter(){
        return 2 * (this.length + this.width);
    }

    void print(char sign) {
        for (int i = 1; i <= this.width; i++) {
            for (int j = 1; j <= this.length; j++) {
                System.out.print(sign);
            }
            System.out.println();
        }
    }

    String getInfo(){
        return "长:" + this.length + ",宽:" + this.width +",面积:" + this.area() +",周长:" + this.perimeter();
    }
}
复制代码

测试类

package com.atguigu.test04.method;

public class TestRectangle {
    public static void main(String[] args) {
        Rectangle r1 = new Rectangle();
        Rectangle r2 = new Rectangle();

        System.out.println("r1对象:" + r1.getInfo());
        System.out.println("r2对象:" + r2.getInfo());

        r1.length = 10;
        r1.width = 2;
        System.out.println("r1对象:" + r1.getInfo());
        System.out.println("r2对象:" + r2.getInfo());

        r1.print('#');
        System.out.println("---------------------");
        r1.print('&');

        System.out.println("---------------------");
        r2.print('#');
        System.out.println("---------------------");
        r2.print('%');
    }
}
复制代码

省略this.

package com.atguigu.test04.method;

public class Rectangle {
    int length;
    int width;

    int area() {
        return length * width;
    }

    int perimeter(){
        return 2 * (length + width);
    }

    void print(char sign) {
        for (int i = 1; i <= width; i++) {
            for (int j = 1; j <= length; j++) {
                System.out.print(sign);
            }
            System.out.println();
        }
    }

    String getInfo(){
        return "长:" + length + ",宽:" + width +",面积:" + area() +",周长:" + perimeter();
    }
}
复制代码

方法调用内存分析

  • 方法不调用不执行,调用一次执行一次,每次调用会在栈中有一个入栈动作,即给当前方法开辟一块独立的内存区域,用于存储当前方法的局部变量的值

  • 当方法执行结束后,会释放该内存,称为出栈

  • 如果方法有返回值,就会把结果返回调用处,如果没有返回值,就直接结束,回到调用处继续执行下一条指令

栈结构:先进后出,后进先出

package com.atguigu.test04.method;

public class MethodMemory {
    public static void main(String[] args) {
        Rectangle r1 = new Rectangle();
        Rectangle r2 = new Rectangle();
        r1.length = 10;
        r1.width = 2;
        r1.print('#');
        System.out.println("r1对象:" + r1.getInfo());
        System.out.println("r2对象:" + r2.getInfo());
    }
}
复制代码

实例变量与局部变量的区别

声明位置和方式

  • 实例变量:在类中方法外

  • 局部变量:在方法体{}中或方法的形参列表、代码块中

在内存中存储的位置不同

  • 实例变量:堆

  • 局部变量:栈

生命周期

  • 实例变量:和对象的生命周期一样,随着对象的创建而存在,随着对象被GC回收而消亡,
    而且每一个对象的实例变量是独立的。

  • 局部变量:和方法调用的生命周期一样,每一次方法被调用而在存在,随着方法执行的结束而消亡,
    而且每一次方法调用都是独立。

作用域

  • 实例变量:通过对象就可以使用,本类中this.,没有歧义还可以省略this.,其他类中对象.

  • 局部变量:出了作用域就不能使用

修饰符

实例变量:public,protected,private,final,volatile,transient 等

局部变量:只能加 final

默认值

实例变量:有默认值

局部变量:没有,必须手动初始化;其中的形参比较特殊,靠实参给它初始化

分类:
后端