5.2 方法声明与调用
前置知识:知道方法用于封装行为
预计时间:25 分钟
完成标志:能在 Java 17 类中声明、调用静态方法并处理作用域
一个完整可运行类
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);
}
}mkdir -p out
javac -d out MethodsDemo.java
java -cp out MethodsDemo预期输出:
=== 方法示例 ===
8方法可以写在 main 前面或后面;Java 编译整个类型声明,不按文本顺序要求先定义再调用。
static 与实例方法
static int add(int left, int right) {
return left + right;
}静态方法属于类,可写 MethodsDemo.add(3, 5)。同一类的静态上下文里通常省略类名。
实例方法需要接收者对象:
class Counter {
private int value;
int increment() {
value++;
return value;
}
}
Counter counter = new Counter();
System.out.println(counter.increment());当前先使用静态方法练调用。实例、字段和 this 在面向对象章节展开。不要把 static 解释成“程序启动时方法已经被创建”,它描述成员与类的关系。
方法名与参数列表形成调用入口
static int add(int left, int right) { ... }方法签名在 Java 语言规范中的核心是方法名和形式参数类型(还涉及类型参数适配等正式定义),不包含返回类型,也不包含参数变量名。因此下面两项不能仅靠返回类型或参数名共存:
// static int convert(int value) { ... }
// static long convert(int number) { ... } // 重复签名参数名服务方法体和读者;调用匹配看类型与顺序。
参数与局部变量的作用域
static int addFee(int price, int fee) {
int total = price + fee;
return total;
}作用域是源码中的可见范围:price、fee 在方法体中可见,total 从声明处到所属块末尾可见。每次调用另有一组独立的参数和局部变量;调用结束不改变源码作用域。被其他引用持有的对象还可能继续存在,因此要区分作用域、一次调用的存续时间与对象生命周期。
同一代码块不能重复声明同名局部变量:
int total = 1;
// int total = 2;实参从左到右求值
static int mark(String name, int value) {
System.out.println(name);
return value;
}
int sum = add(mark("left", 3), mark("right", 5));先打印 left,再打印 right。即使规则确定,也不要用依赖复杂副作用的实参制造阅读谜题。
返回路径与不可达语句
有返回值的方法必须让所有正常完成路径提供值:
static String sign(int value) {
if (value > 0) {
return "positive";
}
if (value < 0) {
return "negative";
}
return "zero";
}无条件 return 后的语句不可达,会编译失败:
static int answer() {
return 42;
// System.out.println("never");
}抛异常的路径突然结束,也不需要返回普通值。
方法命名与粒度
使用动词或动词短语表达行为:calculateTotal、isEligible、loadConfig。布尔方法常用 is、has、can,但以领域含义为准。
方法长度没有通用行数上限。更可靠的信号是:是否承担多个变化原因、是否需要大量上下文才能命名、是否难以独立测试、控制流是否嵌套过深。
专业速查
| 需要判断 | 规则 |
|---|---|
| 静态方法调用 | Type.method(...) |
| 实例方法调用 | receiver.method(...) |
| 方法能否后定义 | 可以,编译器处理整个类型 |
| 签名含返回类型吗 | 不含 |
| 参数名影响重载吗 | 不影响 |
| 局部变量作用域 | 所属块;不等同对象生命周期 |
离开这一页前
对照 MethodsDemo 和 Counter,指出静态调用所属的类与实例调用的接收者,再解释为什么返回类型和参数名不能区分重载。最后检查每条正常路径是否返回兼容值,并把局部变量作用域与对象生命周期分开描述。
规范入口:JLS §8.4:方法声明。