跳到内容

第 1 卷 / 第 5 章 / 第 2 课

5.2 方法声明与调用 ​

前置知识:知道方法用于封装行为

预计时间:25 分钟

完成标志:能在 Java 17 类中声明、调用静态方法并处理作用域

一个完整可运行类 ​

java
public class MethodsDemo {
    static void showBanner() {
        System.out.println("=== 方法示例 ===");
    }

    static int add(int left, int right) {
        return left + right;
    }

    public static void main(String[] args) {
        showBanner();
        int result = add(3, 5);
        System.out.println(result);
    }
}
bash
mkdir -p out
javac -d out MethodsDemo.java
java -cp out MethodsDemo

预期输出:

text
=== 方法示例 ===
8

方法可以写在 main 前面或后面;Java 编译整个类型声明,不按文本顺序要求先定义再调用。

static 与实例方法 ​

java
static int add(int left, int right) {
    return left + right;
}

静态方法属于类,可写 MethodsDemo.add(3, 5)。同一类的静态上下文里通常省略类名。

实例方法需要接收者对象:

java
class Counter {
    private int value;

    int increment() {
        value++;
        return value;
    }
}

Counter counter = new Counter();
System.out.println(counter.increment());

当前先使用静态方法练调用。实例、字段和 this 在面向对象章节展开。不要把 static 解释成“程序启动时方法已经被创建”,它描述成员与类的关系。

方法名与参数列表形成调用入口 ​

java
static int add(int left, int right) { ... }

方法签名在 Java 语言规范中的核心是方法名和形式参数类型(还涉及类型参数适配等正式定义),不包含返回类型,也不包含参数变量名。因此下面两项不能仅靠返回类型或参数名共存:

java
// static int convert(int value) { ... }
// static long convert(int number) { ... } // 重复签名

参数名服务方法体和读者;调用匹配看类型与顺序。

参数与局部变量的作用域 ​

java
static int addFee(int price, int fee) {
    int total = price + fee;
    return total;
}

作用域是源码中的可见范围:price、fee 在方法体中可见,total 从声明处到所属块末尾可见。每次调用另有一组独立的参数和局部变量;调用结束不改变源码作用域。被其他引用持有的对象还可能继续存在,因此要区分作用域、一次调用的存续时间与对象生命周期。

同一代码块不能重复声明同名局部变量:

java
int total = 1;
// int total = 2;

实参从左到右求值 ​

java
static int mark(String name, int value) {
    System.out.println(name);
    return value;
}

int sum = add(mark("left", 3), mark("right", 5));

先打印 left,再打印 right。即使规则确定,也不要用依赖复杂副作用的实参制造阅读谜题。

返回路径与不可达语句 ​

有返回值的方法必须让所有正常完成路径提供值:

java
static String sign(int value) {
    if (value > 0) {
        return "positive";
    }
    if (value < 0) {
        return "negative";
    }
    return "zero";
}

无条件 return 后的语句不可达,会编译失败:

java
static int answer() {
    return 42;
    // System.out.println("never");
}

抛异常的路径突然结束,也不需要返回普通值。

方法命名与粒度 ​

使用动词或动词短语表达行为:calculateTotal、isEligible、loadConfig。布尔方法常用 is、has、can,但以领域含义为准。

方法长度没有通用行数上限。更可靠的信号是:是否承担多个变化原因、是否需要大量上下文才能命名、是否难以独立测试、控制流是否嵌套过深。

专业速查 ​

需要判断规则
静态方法调用Type.method(...)
实例方法调用receiver.method(...)
方法能否后定义可以,编译器处理整个类型
签名含返回类型吗不含
参数名影响重载吗不影响
局部变量作用域所属块;不等同对象生命周期

离开这一页前 ​

对照 MethodsDemo 和 Counter,指出静态调用所属的类与实例调用的接收者,再解释为什么返回类型和参数名不能区分重载。最后检查每条正常路径是否返回兼容值,并把局部变量作用域与对象生命周期分开描述。

→ 下一步:参数、返回值与值传递

规范入口:JLS §8.4:方法声明。

Built with VitePress | Software Systems Atlas