public 关键字

概述

public 关键字是Java中最宽松的访问修饰符,被修饰的成员可以在任何地方被访问。它是面向对象编程中封装性的重要组成部分。

语法格式

public class ClassName { }           // 公共类
public interface InterfaceName { }   // 公共接口
public int variable;                 // 公共变量
public void method() { }             // 公共方法
public ClassName() { }               // 公共构造器

基本用法

公共类

// 文件名必须与public类名相同
public class Calculator {
    public static void main(String[] args) {
        Calculator calc = new Calculator();
        int result = calc.add(5, 3);
        System.out.println("结果:" + result);
    }

    public int add(int a, int b) {
        return a + b;
    }
}

公共方法和变量

public class Student {
    // public 成员变量(不推荐直接public字段)
    public String studentId;

    // private 成员变量
    private String name;
    private int age;

    // public 构造器
    public Student(String studentId, String name, int age) {
        this.studentId = studentId;
        this.name = name;
        this.age = age;
    }

    // public getter方法
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    // public setter方法
    public void setName(String name) {
        if (name != null && !name.trim().isEmpty()) {
            this.name = name;
        }
    }

    public void setAge(int age) {
        if (age >= 0 && age <= 150) {
            this.age = age;
        }
    }

    // public 实例方法
    public void displayInfo() {
        System.out.println("学号:" + studentId);
        System.out.println("姓名:" + name);
        System.out.println("年龄:" + age);
    }

    // public 静态方法
    public static void printSchoolInfo() {
        System.out.println("这里是某某大学");
    }
}

跨包访问

// 包 com.example.model
package com.example.model;

public class User {
    public String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public boolean validatePassword(String inputPassword) {
        return password.equals(inputPassword);
    }

    public void changePassword(String newPassword) {
        if (newPassword != null && newPassword.length() >= 6) {
            this.password = newPassword;
        }
    }
}

// 包 com.example.service
package com.example.service;

import com.example.model.User;

public class UserService {
    public boolean authenticateUser(String username, String password) {
        // 可以访问User类的public成员
        User user = new User(username, password);
        System.out.println("用户名:" + user.username); // 访问public字段
        return user.validatePassword(password); // 调用public方法
    }

    public void registerUser(String username, String password) {
        User newUser = new User(username, password);
        // user.password = "123"; // 错误:不能访问private字段
        newUser.changePassword(password); // 正确:调用public方法
    }
}

实际应用示例

API设计

// 公共API接口
public interface PaymentProcessor {
    public boolean processPayment(double amount, String cardNumber);
    public String getTransactionId();
    public void refund(String transactionId, double amount);
}

// 公共实现类
public class CreditCardProcessor implements PaymentProcessor {
    private String merchantId;
    private boolean isConnected;

    public CreditCardProcessor(String merchantId) {
        this.merchantId = merchantId;
        this.isConnected = false;
    }

    // 公共方法 - 外部可调用
    public boolean connect() {
        // 连接到支付网关
        this.isConnected = true;
        return true;
    }

    @Override
    public boolean processPayment(double amount, String cardNumber) {
        if (!isConnected) {
            throw new IllegalStateException("未连接到支付网关");
        }

        // 处理支付逻辑
        return validateCard(cardNumber) && amount > 0;
    }

    @Override
    public String getTransactionId() {
        return "TXN_" + System.currentTimeMillis();
    }

    @Override
    public void refund(String transactionId, double amount) {
        System.out.println("退款:" + amount + ",交易ID:" + transactionId);
    }

    // 私有辅助方法
    private boolean validateCard(String cardNumber) {
        return cardNumber != null && cardNumber.length() == 16;
    }
}

工具类

// 公共工具类
public class StringUtils {

    // 私有构造器防止实例化
    private StringUtils() {
        throw new UnsupportedOperationException("工具类不能实例化");
    }

    // 公共静态方法
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    public static boolean isBlank(String str) {
        return str == null || str.trim().length() == 0;
    }

    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
    }

    public static String reverse(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return new StringBuilder(str).reverse().toString();
    }

    public static int countWords(String str) {
        if (isBlank(str)) {
            return 0;
        }
        return str.trim().split("\\s+").length;
    }
}

// 使用工具类
public class StringUtilsExample {
    public static void main(String[] args) {
        // 所有方法都是public static,可以直接调用
        System.out.println("是否为空:" + StringUtils.isEmpty(""));
        System.out.println("首字母大写:" + StringUtils.capitalize("hello"));
        System.out.println("反转字符串:" + StringUtils.reverse("world"));
        System.out.println("单词数量:" + StringUtils.countWords("Hello World Java"));
    }
}

配置类

// 公共配置类
public class DatabaseConfig {

    // 公共常量
    public static final String DEFAULT_DRIVER = "com.mysql.cj.jdbc.Driver";
    public static final int DEFAULT_PORT = 3306;
    public static final int MAX_CONNECTIONS = 100;

    // 公共配置属性
    public String host;
    public int port;
    public String database;
    public String username;

    // 私有密码字段
    private String password;

    // 公共构造器
    public DatabaseConfig(String host, String database, String username, String password) {
        this.host = host;
        this.port = DEFAULT_PORT;
        this.database = database;
        this.username = username;
        this.password = password;
    }

    // 公共方法
    public String getConnectionUrl() {
        return "jdbc:mysql://" + host + ":" + port + "/" + database;
    }

    public void setPassword(String password) {
        if (password != null && password.length() >= 8) {
            this.password = password;
        } else {
            throw new IllegalArgumentException("密码长度至少8位");
        }
    }

    // 公共方法,但不直接暴露密码
    public boolean validateConnection() {
        return host != null && database != null && 
               username != null && password != null;
    }

    // 公共显示方法(隐藏敏感信息)
    public void displayConfig() {
        System.out.println("主机:" + host);
        System.out.println("端口:" + port);
        System.out.println("数据库:" + database);
        System.out.println("用户名:" + username);
        System.out.println("密码:[隐藏]");
    }
}

访问级别对比

public class AccessLevelDemo {
    public String publicField = "任何地方都可访问";
    protected String protectedField = "同包或子类可访问";
    String packageField = "同包可访问";
    private String privateField = "仅本类可访问";

    public void publicMethod() {
        System.out.println("public方法:" + publicField);
        System.out.println("protected方法:" + protectedField);
        System.out.println("package方法:" + packageField);
        System.out.println("private方法:" + privateField);
    }

    protected void protectedMethod() {
        System.out.println("protected方法");
    }

    void packageMethod() {
        System.out.println("package方法");
    }

    private void privateMethod() {
        System.out.println("private方法");
    }
}

// 不同包中的测试
package com.example.test;

import com.example.AccessLevelDemo;

public class AccessTest {
    public static void main(String[] args) {
        AccessLevelDemo demo = new AccessLevelDemo();

        // 可以访问
        System.out.println(demo.publicField);
        demo.publicMethod();

        // 以下访问会编译错误(假设不在同一包)
        // System.out.println(demo.protectedField);  // 错误
        // System.out.println(demo.packageField);    // 错误
        // System.out.println(demo.privateField);    // 错误
        // demo.protectedMethod();                   // 错误
        // demo.packageMethod();                     // 错误
        // demo.privateMethod();                     // 错误
    }
}

最佳实践

1. 最小权限原则

public class BankAccount {
    // 不要随意使用public字段
    // public double balance; // 不好的做法

    private double balance; // 好的做法
    private String accountNumber;

    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    // 提供必要的public接口
    public double getBalance() {
        return balance;
    }

    public boolean deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            return true;
        }
        return false;
    }

    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            return true;
        }
        return false;
    }
}

2. API设计

// 良好的public API设计
public class Calculator {

    // 公共接口,隐藏实现细节
    public double add(double a, double b) {
        return performOperation(a, b, Operation.ADD);
    }

    public double subtract(double a, double b) {
        return performOperation(a, b, Operation.SUBTRACT);
    }

    public double multiply(double a, double b) {
        return performOperation(a, b, Operation.MULTIPLY);
    }

    public double divide(double a, double b) {
        if (b == 0) {
            throw new IllegalArgumentException("除数不能为0");
        }
        return performOperation(a, b, Operation.DIVIDE);
    }

    // 私有实现,外部不可见
    private enum Operation {
        ADD, SUBTRACT, MULTIPLY, DIVIDE
    }

    private double performOperation(double a, double b, Operation op) {
        switch (op) {
            case ADD: return a + b;
            case SUBTRACT: return a - b;
            case MULTIPLY: return a * b;
            case DIVIDE: return a / b;
            default: throw new UnsupportedOperationException();
        }
    }
}

注意事项

  1. 安全性考虑

    public class SecurityExample {
        // 避免直接暴露可变对象
        private List<String> items = new ArrayList<>();
    
        // 不好的做法
        // public List<String> getItems() {
        //     return items; // 外部可以修改内部状态
        // }
    
        // 好的做法
        public List<String> getItems() {
            return new ArrayList<>(items); // 返回副本
        }
    
        // 或者返回不可变视图
        public List<String> getItemsReadOnly() {
            return Collections.unmodifiableList(items);
        }
    }
    
  2. 主类规范

    // 文件名:MainClass.java
    public class MainClass {
        public static void main(String[] args) {
            // 主方法必须是public
        }
    }
    

public关键字是Java访问控制的基础,正确使用它对于设计良好的API和维护代码安全性非常重要。

powered by Gitbook© 2025 编外计划 | 最后修改: 2025-07-28 16:25:54

results matching ""

    No results matching ""