Java 函数(方法)

在 Java 中,函数被称为”方法”(Method),是类中定义的可执行代码块。

方法定义

基本语法

public class MethodExample {
    // 方法定义语法:
    // [访问修饰符] [static] 返回类型 方法名(参数列表) {
    //     方法体
    //     return 返回值;  // 如果有返回值
    // }
    
    // 无参数、无返回值的方法
    public void sayHello() {
        System.out.println("Hello, World!");
    }
    
    // 有参数、无返回值的方法
    public void greet(String name) {
        System.out.println("Hello, " + name + "!");
    }
    
    // 有参数、有返回值的方法
    public int add(int a, int b) {
        return a + b;
    }
    
    // 多个参数的方法
    public double calculateAverage(double num1, double num2, double num3) {
        return (num1 + num2 + num3) / 3.0;
    }
    
    // 无参数、有返回值的方法
    public String getCurrentTime() {
        return java.time.LocalTime.now().toString();
    }
}

方法调用

public class MethodCall {
    public static void main(String[] args) {
        MethodExample example = new MethodExample();
        
        // 调用无参数方法
        example.sayHello();
        
        // 调用有参数方法
        example.greet("张三");
        
        // 调用有返回值方法
        int sum = example.add(10, 20);
        System.out.println("和:" + sum);
        
        // 返回值可以直接使用
        System.out.println("平均值:" + example.calculateAverage(10, 20, 30));
    }
}

方法参数

值传递

public class ParameterPassing {
    // Java 中参数传递是值传递(对于基本类型)
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("方法内:a = " + a + ", b = " + b);
    }
    
    public static void main(String[] args) {
        int x = 10, y = 20;
        System.out.println("调用前:x = " + x + ", y = " + y);
        swap(x, y);
        System.out.println("调用后:x = " + x + ", y = " + y);
        // 输出:
        // 调用前:x = 10, y = 20
        // 方法内:a = 20, b = 10
        // 调用后:x = 10, y = 20(x 和 y 的值没有改变)
    }
}

引用传递

public class ReferencePassing {
    // 对于引用类型,传递的是引用的副本
    public static void changeArray(int[] arr) {
        arr[0] = 100;  // 修改数组元素
        System.out.println("方法内:arr[0] = " + arr[0]);
    }
    
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        System.out.println("调用前:numbers[0] = " + numbers[0]);
        changeArray(numbers);
        System.out.println("调用后:numbers[0] = " + numbers[0]);
        // 输出:
        // 调用前:numbers[0] = 1
        // 方法内:arr[0] = 100
        // 调用后:numbers[0] = 100(数组元素被修改了)
    }
}

可变参数(Varargs)

public class VarargsExample {
    // 可变参数:使用 ... 表示
    // 可变参数必须是最后一个参数
    public static int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    // 可变参数可以和其他参数一起使用
    public static void printInfo(String name, int... scores) {
        System.out.print(name + " 的分数:");
        for (int score : scores) {
            System.out.print(score + " ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        // 可以传入任意数量的参数
        System.out.println(sum(1, 2, 3));           // 6
        System.out.println(sum(1, 2, 3, 4, 5));     // 15
        System.out.println(sum());                  // 0(也可以不传参数)
        
        printInfo("张三", 90, 85, 92);
    }
}

方法重载(Overloading)

public class MethodOverloading {
    // 方法重载:同一个类中可以有多个同名方法,但参数列表必须不同
    
    // 重载1:两个 int 参数
    public int add(int a, int b) {
        return a + b;
    }
    
    // 重载2:三个 int 参数
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 重载3:两个 double 参数
    public double add(double a, double b) {
        return a + b;
    }
    
    // 重载4:两个 String 参数
    public String add(String a, String b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        MethodOverloading obj = new MethodOverloading();
        
        System.out.println(obj.add(10, 20));              // 调用重载1
        System.out.println(obj.add(10, 20, 30));         // 调用重载2
        System.out.println(obj.add(10.5, 20.5));          // 调用重载3
        System.out.println(obj.add("Hello", " World"));   // 调用重载4
    }
}

静态方法

public class StaticMethod {
    // 静态方法:使用 static 关键字
    // 静态方法属于类,不依赖于对象实例
    // 可以直接通过类名调用
    
    public static void staticMethod() {
        System.out.println("这是静态方法");
    }
    
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 实例方法:需要创建对象才能调用
    public void instanceMethod() {
        System.out.println("这是实例方法");
    }
    
    public static void main(String[] args) {
        // 调用静态方法:直接通过类名调用
        StaticMethod.staticMethod();
        int sum = StaticMethod.add(10, 20);
        System.out.println("和:" + sum);
        
        // 调用实例方法:需要创建对象
        StaticMethod obj = new StaticMethod();
        obj.instanceMethod();
        
        // 注意:静态方法中不能直接访问实例变量和实例方法
        // 但可以通过对象引用访问
    }
}

方法返回值

void 方法

public class VoidMethod {
    // void 表示方法没有返回值
    public void printMessage(String msg) {
        System.out.println(msg);
        // 不需要 return 语句
    }
    
    // void 方法也可以使用 return 提前退出
    public void checkAge(int age) {
        if (age < 0) {
            System.out.println("年龄无效");
            return;  // 提前退出,不执行后面的代码
        }
        System.out.println("年龄:" + age);
    }
}

有返回值的方法

public class ReturnValue {
    // 返回 int 类型
    public int getNumber() {
        return 42;
    }
    
    // 返回 String 类型
    public String getName() {
        return "张三";
    }
    
    // 返回数组
    public int[] getNumbers() {
        return new int[]{1, 2, 3, 4, 5};
    }
    
    // 条件返回
    public String getGrade(int score) {
        if (score >= 90) {
            return "优秀";
        } else if (score >= 80) {
            return "良好";
        } else if (score >= 60) {
            return "及格";
        } else {
            return "不及格";
        }
    }
    
    // 多个返回点
    public int findMax(int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            return -1;  // 返回 -1 表示未找到
        }
        
        int max = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            if (numbers[i] > max) {
                max = numbers[i];
            }
        }
        return max;
    }
}

递归方法

public class Recursion {
    // 递归:方法调用自身
    
    // 计算阶乘:n! = n * (n-1)!
    public static int factorial(int n) {
        // 基本情况(递归终止条件)
        if (n <= 1) {
            return 1;
        }
        // 递归调用
        return n * factorial(n - 1);
    }
    
    // 计算斐波那契数列:F(n) = F(n-1) + F(n-2)
    public static int fibonacci(int n) {
        // 基本情况
        if (n <= 1) {
            return n;
        }
        // 递归调用
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
    
    // 计算最大公约数(欧几里得算法)
    public static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }
    
    public static void main(String[] args) {
        System.out.println("5! = " + factorial(5));  // 120
        System.out.println("fib(10) = " + fibonacci(10));  // 55
        System.out.println("gcd(48, 18) = " + gcd(48, 18));  // 6
    }
}

方法的最佳实践

1. 方法命名

public class NamingBestPractice {
    // 方法名使用动词或动词短语,小驼峰命名
    public void calculateTotal() { }
    public String getUserName() { }
    public boolean isValid() { }
    public void setAge(int age) { }
    
    // 布尔方法通常以 is、has、can 开头
    public boolean isActive() { return true; }
    public boolean hasPermission() { return false; }
    public boolean canEdit() { return true; }
}

2. 方法长度

// 好的做法:方法简短,职责单一
public class GoodMethod {
    public void processUser(User user) {
        validateUser(user);
        saveUser(user);
        sendNotification(user);
    }
    
    private void validateUser(User user) {
        // 验证逻辑
    }
    
    private void saveUser(User user) {
        // 保存逻辑
    }
    
    private void sendNotification(User user) {
        // 通知逻辑
    }
}
 
// 不好的做法:方法过长,职责不清
public class BadMethod {
    public void doEverything(User user) {
        // 验证逻辑
        // 保存逻辑
        // 通知逻辑
        // 其他逻辑...
        // 方法过长,难以理解和维护
    }
}

3. 参数数量

// 好的做法:参数数量少(通常不超过 3-4 个)
public class GoodParameters {
    public void createUser(String name, String email) { }
    
    // 如果参数多,可以使用对象封装
    public void createUser(UserInfo userInfo) { }
}
 
// 不好的做法:参数过多
public class BadParameters {
    public void createUser(String name, String email, String phone, 
                          String address, int age, String gender) {
        // 参数太多,容易出错
    }
}

实际应用示例

示例1:工具类方法

public class MathUtils {
    // 工具类通常使用静态方法
    public static int max(int a, int b) {
        return (a > b) ? a : b;
    }
    
    public static int min(int a, int b) {
        return (a < b) ? a : b;
    }
    
    public static double power(double base, int exponent) {
        double result = 1.0;
        for (int i = 0; i < exponent; i++) {
            result *= base;
        }
        return result;
    }
    
    public static boolean isEven(int number) {
        return number % 2 == 0;
    }
    
    public static void main(String[] args) {
        System.out.println("max(10, 20) = " + max(10, 20));
        System.out.println("min(10, 20) = " + min(10, 20));
        System.out.println("power(2, 3) = " + power(2, 3));
        System.out.println("isEven(10) = " + isEven(10));
    }
}

示例2:字符串处理方法

public class StringUtils {
    public static String reverse(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        StringBuilder sb = new StringBuilder(str);
        return sb.reverse().toString();
    }
    
    public static boolean isPalindrome(String str) {
        if (str == null) {
            return false;
        }
        String reversed = reverse(str);
        return str.equals(reversed);
    }
    
    public static int countWords(String str) {
        if (str == null || str.trim().isEmpty()) {
            return 0;
        }
        return str.trim().split("\\s+").length;
    }
    
    public static void main(String[] args) {
        System.out.println(reverse("Hello"));  // "olleH"
        System.out.println(isPalindrome("level"));  // true
        System.out.println(countWords("Hello World Java"));  // 3
    }
}

总结

Java 方法要点:

  • 方法定义:访问修饰符、返回类型、方法名、参数列表
  • 方法调用:通过对象或类名调用
  • 参数传递:基本类型值传递,引用类型传递引用
  • 方法重载:同名方法,不同参数列表
  • 静态方法:属于类,可直接通过类名调用
  • 递归:方法调用自身
  • 最佳实践:命名规范、方法长度、参数数量

掌握方法是编写 Java 程序的基础。


相关链接


java 方法 函数 面向对象