第 5 章 / 共 20 章
方法
签名、重载、可变参数、static、方法引用
方法定义
格式:[修饰符] 返回类型 方法名(参数列表) { 方法体 }。返回类型 void 表示不返回值。
// Methods.java
public class Methods {
// static 方法可以直接通过类名调用
static int add(int a, int b) {
return a + b;
}
static void greet(String name) {
System.out.println("Hello, " + name);
}
public static void main(String[] args) {
System.out.println(add(2, 3));
greet("Alice");
}
}重载(Overloading)
同一类里方法名相同但参数列表不同(个数 / 类型 / 顺序),编译器按调用处的参数类型选最匹配的版本。返回类型不参与重载判断。
// Overload.java
public class Overload {
static int sum(int a, int b) { return a + b; }
static double sum(double a, double b) { return a + b; }
static int sum(int a, int b, int c) { return a + b + c; }
public static void main(String[] args) {
System.out.println(sum(1, 2)); // 调用第一个
System.out.println(sum(1.5, 2.5)); // 调用第二个
System.out.println(sum(1, 2, 3)); // 调用第三个
}
}可变参数 String...
T... 等价于内部是 T[] 数组,调用时可以传任意个该类型实参。可变参数必须是参数列表的最后一个。
// Varargs.java
public class Varargs {
static int max(int... nums) {
if (nums.length == 0) {
throw new IllegalArgumentException("need at least one");
}
int m = nums[0];
for (int n : nums) {
if (n > m) m = n;
}
return m;
}
public static void main(String[] args) {
System.out.println(max(3, 1, 4, 1, 5, 9, 2, 6)); // 9
// 也可以直接传数组
int[] arr = {7, 2, 8};
System.out.println(max(arr)); // 8
}
}static 方法 vs 实例方法
static 方法属于类,通过 类名.方法名 调用,不能访问实例字段;实例方法属于对象,必须先有 new XX()。第 6 章会展开类与对象,这里先看用法对比。
// StaticVsInstance.java
public class StaticVsInstance {
private String name;
public StaticVsInstance(String name) {
this.name = name;
}
void hello() { // 实例方法
System.out.println("hi, " + name);
}
static String capitalize(String s) { // static 方法
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
public static void main(String[] args) {
// static 直接调
System.out.println(capitalize("alice")); // Alice
// 实例方法必须先 new
StaticVsInstance obj = new StaticVsInstance("Bob");
obj.hello();
}
}参数传值机制
Java 永远是"按值传递"。但对引用类型,传过去的是引用的副本——函数内通过引用能修改对象内部,但重新赋值 obj = new ... 不会影响外面。
// PassByValue.java
import java.util.ArrayList;
import java.util.List;
public class PassByValue {
static void changeInt(int n) {
n = 99; // 改的是本地副本
}
static void mutateList(List<Integer> list) {
list.add(99); // 通过引用改了对象内部
}
static void reassignList(List<Integer> list) {
list = new ArrayList<>(); // 改的是本地引用,不影响外面
list.add(-1);
}
public static void main(String[] args) {
int n = 1;
changeInt(n);
System.out.println(n); // 1
List<Integer> nums = new ArrayList<>(List.of(1, 2, 3));
mutateList(nums);
System.out.println(nums); // [1, 2, 3, 99]
reassignList(nums);
System.out.println(nums); // [1, 2, 3, 99] 没变
}
}方法引用 Class::method
Java 8 起方法可以作为"值"传递。Class::staticMethod、obj::instanceMethod、Class::instanceMethod、Class::new 四种形式。第 14 章 Lambda 会更深入。
// MethodRef.java
import java.util.List;
public class MethodRef {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Carol");
// 方法引用:System.out::println 等价于 s -> System.out.println(s)
names.forEach(System.out::println);
// 静态方法引用:Integer::parseInt 等价于 s -> Integer.parseInt(s)
List<String> nums = List.of("1", "2", "3");
int sum = nums.stream().mapToInt(Integer::parseInt).sum();
System.out.println("sum=" + sum);
}
}