Java 方法(Method)语法基础

31 阅读6分钟

📖 方法基本概念

1. 什么是方法?

  • 方法是一段可重复使用的代码块
  • 用于执行特定的任务或功能
  • 提高代码的复用性可维护性

2. 方法的基本语法

[访问修饰符] [static/final] 返回值类型 方法名(参数列表) {
    // 方法体
    [return 返回值;]
}

🏗️ 方法组成要素

1. 访问修饰符(Access Modifiers)

public class MethodDemo {
    
    // 1. public - 任何地方都可访问
    public void publicMethod() {
        System.out.println("公共方法");
    }
    
    // 2. private - 仅本类可访问
    private void privateMethod() {
        System.out.println("私有方法");
    }
    
    // 3. protected - 同包或子类可访问
    protected void protectedMethod() {
        System.out.println("受保护方法");
    }
    
    // 4. 默认(不写)- 同包可访问
    void defaultMethod() {
        System.out.println("默认方法");
    }
}

2. 返回值类型(Return Type)

public class ReturnTypeDemo {
    
    // 1. 有返回值 - 必须使用return语句
    public int add(int a, int b) {
        return a + b;  // 返回int类型
    }
    
    public String getName() {
        return "张三";  // 返回String类型
    }
    
    public double[] getNumbers() {
        return new double[]{1.5, 2.5, 3.5};  // 返回数组
    }
    
    // 2. 无返回值 - 使用void关键字
    public void printMessage() {
        System.out.println("Hello, World!");
        // 不需要return语句,或使用 return;(无返回值)
    }
    
    // 3. 返回对象
    public Student createStudent() {
        return new Student("李四", 20);
    }
}

3. 方法名(Method Name)

java

public class MethodNaming {
    
    // 规范:小驼峰命名,动词开头
    public void calculateSum() {}      // ✅ 好
    public String getUserName() {}     // ✅ 好
    public boolean isValid() {}        // ✅ 好
    
    // 不推荐的命名
    public void sum() {}               // ❌ 不够明确
    public void get() {}               // ❌ 过于简单
}

4. 参数列表(Parameters)

public class ParameterDemo {
    
    // 1. 无参数
    public void sayHello() {
        System.out.println("Hello!");
    }
    
    // 2. 单个参数
    public void greet(String name) {
        System.out.println("Hello, " + name);
    }
    
    // 3. 多个参数
    public int calculate(int a, int b, int c) {
        return a + b + c;
    }
    
    // 4. 相同类型多个参数
    public double average(double num1, double num2, double num3) {
        return (num1 + num2 + num3) / 3;
    }
    
    // 5. 可变参数(Varargs)- Java 5+
    public int sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        return total;
    }
    
    // 使用示例
    public void test() {
        sum(1, 2);           // 2个参数
        sum(1, 2, 3, 4, 5);  // 5个参数
        sum();               // 0个参数
    }
}

5. 方法体(Method Body)

public class MethodBodyDemo {
    
    public void processData(int value) {
        // 局部变量 - 只在方法内部有效
        int localVar = value * 2;
        
        // 控制结构
        if (localVar > 100) {
            System.out.println("值大于100");
        } else {
            System.out.println("值小于等于100");
        }
        
        // 循环
        for (int i = 0; i < 5; i++) {
            System.out.println("循环次数: " + i);
        }
    }
    
    // 简洁的方法体
    public boolean isEven(int number) {
        return number % 2 == 0;  // 直接返回表达式结果
    }
}

🔄 方法调用

1. 静态方法调用

public class Calculator {
    
    // 静态方法
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        // 直接通过类名调用
        int result = Calculator.add(10, 20);
        System.out.println("结果: " + result);
        
        // 在同一个类中,可以省略类名
        int result2 = add(30, 40);
    }
}

2. 实例方法调用

public class Student {
    private String name;
    
    // 实例方法
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return this.name;
    }
    
    public void introduce() {
        System.out.println("我叫" + name);
    }
    
    public static void main(String[] args) {
        // 必须先创建对象
        Student student = new Student();
        
        // 通过对象调用实例方法
        student.setName("张三");
        System.out.println(student.getName());
        student.introduce();
    }
}

🎯 方法重载(Overloading)

1. 重载规则

public class OverloadDemo {
    
    // 1. 参数类型不同
    public int add(int a, int b) {
        return a + b;
    }
    
    public double add(double a, double b) {
        return a + b;
    }
    
    // 2. 参数数量不同
    public int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 3. 参数顺序不同(类型必须不同)
    public void printInfo(String name, int age) {
        System.out.println(name + ", " + age + "岁");
    }
    
    public void printInfo(int age, String name) {
        System.out.println(age + "岁的" + name);
    }
    
    // ❌ 不能仅通过返回值类型不同来重载
    // public double add(int a, int b) {  // 编译错误
    //     return a + b;
    // }
    
    // ❌ 不能仅通过访问修饰符不同来重载
    // private int add(int a, int b) {    // 编译错误
    //     return a + b;
    // }
}

2. 重载调用示例

public class TestOverload {
    
    public void process(int num) {
        System.out.println("处理整数: " + num);
    }
    
    public void process(String text) {
        System.out.println("处理字符串: " + text);
    }
    
    public void process(int num, String text) {
        System.out.println("处理整数和字符串: " + num + ", " + text);
    }
    
    public static void main(String[] args) {
        TestOverload test = new TestOverload();
        
        test.process(10);              // 调用 process(int)
        test.process("Hello");         // 调用 process(String)
        test.process(20, "World");     // 调用 process(int, String)
    }
}

📝 特殊方法类型

1. 构造方法(Constructor)

public class Person {
    private String name;
    private int age;
    
    // 默认构造方法(无参)
    public Person() {
        this.name = "未知";
        this.age = 0;
    }
    
    // 带参数构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 构造方法重载
    public Person(String name) {
        this(name, 0);  // 调用另一个构造方法
    }
}

2. 静态方法(Static Method)

public class MathUtils {
    
    // 静态方法 - 属于类,不依赖对象
    public static int max(int a, int b) {
        return a > b ? a : b;
    }
    
    public static double circleArea(double radius) {
        return Math.PI * radius * radius;
    }
    
    // 静态方法中不能使用this
    // 不能直接访问实例变量/方法
}

// 使用
public class Test {
    public static void main(String[] args) {
        int max = MathUtils.max(10, 20);
        double area = MathUtils.circleArea(5.0);
    }
}

3. final方法

public class Parent {
    
    // final方法 - 不能被子类重写
    public final void show() {
        System.out.println("这是父类的final方法");
    }
    
    // 普通方法 - 可以被子类重写
    public void display() {
        System.out.println("这是父类的普通方法");
    }
}

class Child extends Parent {
    // ❌ 不能重写final方法
    // @Override
    // public void show() { }
    
    // ✅ 可以重写普通方法
    @Override
    public void display() {
        System.out.println("这是子类重写的方法");
    }
}

⚠️ 注意事项与最佳实践

1. 方法设计原则

public class BestPractices {
    
    // ✅ 好:单一职责,只做一件事
    public double calculateArea(double radius) {
        return Math.PI * radius * radius;
    }
    
    // ❌ 不好:做太多事情
    public void processUserData(String name, int age, String email) {
        validateName(name);
        validateAge(age);
        validateEmail(email);
        saveToDatabase(name, age, email);
        sendWelcomeEmail(email);
    }
    
    // ✅ 好:合理的方法长度(建议不超过30行)
    public boolean isValidEmail(String email) {
        if (email == null || email.isEmpty()) {
            return false;
        }
        return email.contains("@") && email.contains(".");
    }
    
    // ✅ 好:有意义的返回值
    public boolean isAdult(int age) {
        return age >= 18;  // 返回布尔值,方法名以is开头
    }
}

2. 参数传递机制

public class ParameterPassing {
    
    // 基本类型 - 传值(复制一份)
    public void modifyPrimitive(int num) {
        num = 100;  // 只修改副本,不影响原值
    }
    
    // 引用类型 - 传引用(传递地址)
    public void modifyReference(int[] array) {
        array[0] = 100;  // 修改原数组内容
        array = new int[]{999};  // 指向新数组,不影响原引用
    }
    
    public void test() {
        int num = 10;
        modifyPrimitive(num);
        System.out.println(num);  // 输出: 10
        
        int[] arr = {1, 2, 3};
        modifyReference(arr);
        System.out.println(arr[0]);  // 输出: 100
    }
}

💻 综合示例

/**
 * 银行账户类 - 综合示例
 */
public class BankAccount {
    private String accountNumber;
    private String owner;
    private double balance;
    
    // 构造方法
    public BankAccount(String accountNumber, String owner) {
        this.accountNumber = accountNumber;
        this.owner = owner;
        this.balance = 0.0;
    }
    
    public BankAccount(String accountNumber, String owner, double initialBalance) {
        this(accountNumber, owner);
        this.balance = initialBalance;
    }
    
    // 实例方法
    public void deposit(double amount) {
        if (amount <= 0) {
            System.out.println("存款金额必须大于0");
            return;
        }
        this.balance += amount;
        System.out.println("存款成功,当前余额: " + this.balance);
    }
    
    public boolean withdraw(double amount) {
        if (amount <= 0) {
            System.out.println("取款金额必须大于0");
            return false;
        }
        if (amount > this.balance) {
            System.out.println("余额不足");
            return false;
        }
        this.balance -= amount;
        System.out.println("取款成功,当前余额: " + this.balance);
        return true;
    }
    
    public double getBalance() {
        return this.balance;
    }
    
    public String getAccountInfo() {
        return String.format("账号: %s, 户主: %s, 余额: %.2f", 
                            accountNumber, owner, balance);
    }
    
    // 静态方法 - 计算利息
    public static double calculateInterest(double principal, double rate, int years) {
        return principal * Math.pow(1 + rate, years);
    }
    
    // 方法重载 - 转账
    public boolean transfer(BankAccount target, double amount) {
        if (this.withdraw(amount)) {
            target.deposit(amount);
            return true;
        }
        return false;
    }
    
    public boolean transfer(BankAccount target, double amount, String memo) {
        System.out.println("转账备注: " + memo);
        return transfer(target, amount);
    }
}

// 测试类
public class TestBankAccount {
    public static void main(String[] args) {
        // 创建账户
        BankAccount account1 = new BankAccount("001", "张三", 1000);
        BankAccount account2 = new BankAccount("002", "李四", 500);
        
        // 调用实例方法
        account1.deposit(500);
        account1.withdraw(200);
        
        // 调用重载方法
        account1.transfer(account2, 300);
        account1.transfer(account2, 200, "还款");
        
        // 调用静态方法
        double interest = BankAccount.calculateInterest(10000, 0.035, 5);
        System.out.println("利息: " + interest);
        
        // 获取信息
        System.out.println(account1.getAccountInfo());
    }
}

📌 关键总结

  1. 方法定义:访问修饰符 + 返回值类型 + 方法名 + 参数列表 + 方法体
  2. 返回值:必须有return语句(void除外),且类型要匹配
  3. 参数:可以有0个或多个,支持可变参数
  4. 方法调用:静态方法通过类名,实例方法通过对象
  5. 方法重载:同名方法,参数列表不同(类型、数量、顺序)
  6. 最佳实践:单一职责、合理命名、适度长度、明确返回值