Java 权限修饰符(Access Modifiers)指南

📊 权限修饰符总览

修饰符 同类 同包 子类(不同包) 不同包非子类 级别
private 最严格
默认 (无修饰符) 包级别
protected 子类级别
public 最宽松

一般来说小编大多只使用private和public

🎯 四种权限修饰符详解

1. private(私有访问)

特点

  • 只能在本类内部访问
  • 最严格的访问控制
  • 常用于封装,隐藏实现细节

java

typescript 复制代码
package com.example;

public class PrivateDemo {
    // 私有属性 - 只能在本类中访问
    private String secret = "这是机密信息";
    private int privateNumber = 100;
    
    // 私有方法 - 只能在本类中调用
    private void showSecret() {
        System.out.println("机密信息: " + secret);
    }
    
    // 公共方法提供对私有属性的受控访问
    public String getSecret() {
        // 可以添加验证逻辑
        if (checkPermission()) {
            return secret;
        }
        return "无权访问";
    }
    
    public void setSecret(String newSecret) {
        if (validateSecret(newSecret)) {
            this.secret = newSecret;
        }
    }
    
    private boolean checkPermission() {
        // 权限检查逻辑
        return true;
    }
    
    private boolean validateSecret(String secret) {
        // 验证逻辑
        return secret != null && !secret.trim().isEmpty();
    }
    
    // 在本类中可以自由访问私有成员
    public void testAccess() {
        System.out.println("在本类中访问:");
        System.out.println("直接访问私有属性: " + secret);
        System.out.println("调用私有方法: ");
        showSecret();
        
        // 修改私有属性
        privateNumber = 200;
        System.out.println("修改后: " + privateNumber);
    }
    
    public static void main(String[] args) {
        PrivateDemo demo = new PrivateDemo();
        demo.testAccess();
        
        // 通过公共方法访问私有属性
        System.out.println("\n通过公共方法访问:");
        System.out.println("getSecret(): " + demo.getSecret());
        
        demo.setSecret("新的机密");
        System.out.println("修改后: " + demo.getSecret());
        
        // ❌ 错误:不能直接访问私有成员
        // System.out.println(demo.secret);      // 编译错误
        // demo.showSecret();                   // 编译错误
        // demo.privateNumber = 300;            // 编译错误
    }
}

// 同包中的另一个类
class SamePackageClass {
    void test() {
        PrivateDemo demo = new PrivateDemo();
        
        // ❌ 错误:同包其他类也不能访问private成员
        // System.out.println(demo.secret);      // 编译错误
        // demo.showSecret();                   // 编译错误
        
        // ✅ 正确:只能通过公共方法访问
        System.out.println(demo.getSecret());
    }
}

private 在构造器中的应用

java

csharp 复制代码
public class Singleton {
    // 私有静态变量
    private static Singleton instance;
    
    // 私有构造器 - 防止外部创建实例
    private Singleton() {
        System.out.println("Singleton实例被创建");
    }
    
    // 公共静态方法提供访问
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    
    public void showMessage() {
        System.out.println("Hello Singleton!");
    }
    
    public static void main(String[] args) {
        // ❌ 错误:不能直接new
        // Singleton s = new Singleton();
        
        // ✅ 正确:通过静态方法获取
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        
        System.out.println("s1 == s2: " + (s1 == s2));  // true
        s1.showMessage();
    }
}

2. 默认/包私有(Default/Package-private)

特点

  • 没有明确指定修饰符
  • 同一个包内可以访问
  • 也称为"包访问权限"或"包私有"

java

csharp 复制代码
package com.example;

// 默认类:同包可见
class DefaultClass {
    // 默认属性:同包可见
    String defaultField = "默认属性";
    
    // 默认方法:同包可见
    void defaultMethod() {
        System.out.println("默认方法");
    }
    
    // 公共方法:所有地方可见
    public void publicMethod() {
        System.out.println("公共方法");
    }
}

public class DefaultModifierDemo {
    // 默认属性
    String packagePrivateField = "包私有属性";
    
    // 默认方法
    void packagePrivateMethod() {
        System.out.println("包私有方法");
        System.out.println("可以访问: " + packagePrivateField);
    }
    
    public static void main(String[] args) {
        DefaultModifierDemo demo = new DefaultModifierDemo();
        
        // 在本类中可以访问默认成员
        demo.packagePrivateMethod();
        
        // 在同包中访问另一个类的默认成员
        DefaultClass obj = new DefaultClass();
        System.out.println("\n访问同包的DefaultClass:");
        System.out.println(obj.defaultField);  // ✅ 可以访问
        obj.defaultMethod();                   // ✅ 可以调用
        obj.publicMethod();                    // ✅ 可以调用
    }
}

// 同包中的另一个类
package com.example;

class AnotherClassInSamePackage {
    void test() {
        DefaultModifierDemo demo = new DefaultModifierDemo();
        
        // ✅ 正确:同包可以访问默认成员
        System.out.println(demo.packagePrivateField);
        demo.packagePrivateMethod();
        
        DefaultClass obj = new DefaultClass();
        System.out.println(obj.defaultField);
        obj.defaultMethod();
    }
}

不同包的情况

java

java 复制代码
// 不同包中的类
package other;

import com.example.DefaultModifierDemo;
import com.example.DefaultClass;  // ❌ 编译错误:DefaultClass不是public

public class DifferentPackageClass {
    void test() {
        DefaultModifierDemo demo = new DefaultModifierDemo();
        
        // ❌ 错误:不同包不能访问默认成员
        // System.out.println(demo.packagePrivateField);  // 编译错误
        // demo.packagePrivateMethod();                   // 编译错误
        
        // ✅ 正确:可以访问公共成员
        // demo.publicMethod();  // 如果有的话
        
        // ❌ 错误:不能访问默认类
        // DefaultClass obj = new DefaultClass();  // 编译错误
    }
}

3. protected(受保护访问)

特点

  • 同一个包内可以访问
  • 不同包的子类中可以访问
  • 常用于允许子类访问父类的实现细节

java

csharp 复制代码
package com.base;

public class Parent {
    // protected 属性
    protected String protectedField = "父类的protected属性";
    
    // protected 方法
    protected void protectedMethod() {
        System.out.println("父类的protected方法");
    }
    
    // 默认属性(对比用)
    String defaultField = "父类的默认属性";
    
    // 公共方法
    public void show() {
        System.out.println("在本类中访问:");
        System.out.println("protectedField: " + protectedField);
        System.out.println("defaultField: " + defaultField);
        protectedMethod();
    }
}

// 同包的子类
package com.base;

class SamePackageChild extends Parent {
    public void test() {
        System.out.println("同包子类访问:");
        
        // ✅ 可以访问 protected 成员
        System.out.println("protectedField: " + protectedField);
        protectedMethod();
        
        // ✅ 可以访问默认成员(同包)
        System.out.println("defaultField: " + defaultField);
        
        // 通过 super 访问
        System.out.println("通过super访问: " + super.protectedField);
        super.protectedMethod();
    }
}

// 同包的非子类
package com.base;

class SamePackageNonChild {
    public void test() {
        Parent parent = new Parent();
        
        System.out.println("同包非子类访问:");
        
        // ✅ 可以访问 protected 成员(同包)
        System.out.println("protectedField: " + parent.protectedField);
        parent.protectedMethod();
        
        // ✅ 可以访问默认成员(同包)
        System.out.println("defaultField: " + parent.defaultField);
    }
}

不同包子类的情况

java

java 复制代码
// 不同包的子类
package com.derived;

import com.base.Parent;

public class DifferentPackageChild extends Parent {
    public void test() {
        System.out.println("不同包子类访问:");
        
        // ✅ 可以访问 protected 成员(子类权限)
        System.out.println("protectedField: " + protectedField);
        protectedMethod();
        
        // 通过 super 访问
        System.out.println("通过super访问: " + super.protectedField);
        super.protectedMethod();
        
        // ❌ 错误:不能访问默认成员(不同包)
        // System.out.println(defaultField);  // 编译错误
        
        // ❌ 错误:不能通过父类实例访问 protected 成员
        Parent parent = new Parent();
        // System.out.println(parent.protectedField);  // 编译错误
        // parent.protectedMethod();                   // 编译错误
        
        // ✅ 正确:可以通过自身实例访问
        DifferentPackageChild child = new DifferentPackageChild();
        System.out.println("通过子类实例: " + child.protectedField);
        child.protectedMethod();
    }
}

// 不同包的非子类
package com.derived;

import com.base.Parent;

class DifferentPackageNonChild {
    public void test() {
        Parent parent = new Parent();
        
        System.out.println("不同包非子类访问:");
        
        // ❌ 错误:不能访问 protected 成员
        // System.out.println(parent.protectedField);  // 编译错误
        // parent.protectedMethod();                   // 编译错误
        
        // ❌ 错误:不能访问默认成员
        // System.out.println(parent.defaultField);    // 编译错误
        
        // ✅ 正确:只能访问 public 成员
        parent.show();  // 如果有的话
    }
}

4. public(公共访问)

特点

  • 在任何地方都可以访问
  • 最宽松的访问控制
  • 用于定义对外提供的接口

java

csharp 复制代码
package com.example;

// public 类:所有地方可见
public class PublicDemo {
    // public 属性:所有地方可见
    public String publicField = "公共属性";
    
    // public 方法:所有地方可见
    public void publicMethod() {
        System.out.println("公共方法");
        System.out.println("可以访问: " + publicField);
    }
    
    // 其他权限的方法
    protected void protectedMethod() {
        System.out.println("受保护方法");
    }
    
    void defaultMethod() {
        System.out.println("默认方法");
    }
    
    private void privateMethod() {
        System.out.println("私有方法");
    }
    
    public static void main(String[] args) {
        PublicDemo demo = new PublicDemo();
        
        // 在本类中可以访问所有权限的成员
        demo.publicMethod();
        demo.protectedMethod();
        demo.defaultMethod();
        demo.privateMethod();
    }
}

// 同包的另一个类
package com.example;

class SamePackageClass {
    void test() {
        PublicDemo demo = new PublicDemo();
        
        System.out.println("同包访问:");
        
        // ✅ 可以访问 public 成员
        System.out.println(demo.publicField);
        demo.publicMethod();
        
        // ✅ 可以访问 protected 成员(同包)
        demo.protectedMethod();
        
        // ✅ 可以访问默认成员(同包)
        demo.defaultMethod();
        
        // ❌ 不能访问 private 成员
        // demo.privateMethod();  // 编译错误
    }
}

不同包的情况

java

csharp 复制代码
// 不同包中的类
package other;

import com.example.PublicDemo;

public class DifferentPackageClass {
    void test() {
        PublicDemo demo = new PublicDemo();
        
        System.out.println("不同包访问:");
        
        // ✅ 可以访问 public 成员
        System.out.println(demo.publicField);
        demo.publicMethod();
        
        // ❌ 不能访问 protected 成员(不同包非子类)
        // demo.protectedMethod();  // 编译错误
        
        // ❌ 不能访问默认成员(不同包)
        // demo.defaultMethod();    // 编译错误
        
        // ❌ 不能访问 private 成员
        // demo.privateMethod();    // 编译错误
    }
}

🏗️ 权限修饰符的应用场景

1. 封装:数据隐藏

java

typescript 复制代码
// 银行账户类 - 使用封装保护数据
public class BankAccount {
    // 私有属性:外部不能直接访问
    private String accountNumber;
    private String accountHolder;
    private double balance;
    private String password;
    
    // 公共构造器
    public BankAccount(String accountNumber, String accountHolder, 
                      String password, double initialBalance) {
        this.accountNumber = accountNumber;
        this.accountHolder = accountHolder;
        this.password = password;
        this.balance = initialBalance;
    }
    
    // 公共方法:提供受控的访问
    
    // Getter 方法(只读)
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public String getAccountHolder() {
        return accountHolder;
    }
    
    public double getBalance() {
        return balance;
    }
    
    // 没有 password 的 Getter(安全考虑)
    
    // Setter 方法(有验证)
    public void setAccountHolder(String accountHolder) {
        if (accountHolder != null && !accountHolder.trim().isEmpty()) {
            this.accountHolder = accountHolder;
        }
    }
    
    // 业务方法
    public boolean deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            return true;
        }
        return false;
    }
    
    public boolean withdraw(double amount, String password) {
        if (authenticate(password) && amount > 0 && amount <= balance) {
            balance -= amount;
            return true;
        }
        return false;
    }
    
    // 私有方法:内部使用
    private boolean authenticate(String inputPassword) {
        return this.password.equals(inputPassword);
    }
    
    private void logTransaction(String type, double amount) {
        System.out.println("交易记录: " + type + " $" + amount);
    }
    
    // 受保护方法:给子类扩展用
    protected void applyFee(double fee) {
        if (fee > 0 && balance >= fee) {
            balance -= fee;
        }
    }
    
    public static void main(String[] args) {
        BankAccount account = new BankAccount("123456", "张三", "123456", 1000);
        
        // ✅ 正确:通过公共方法访问
        System.out.println("账户: " + account.getAccountNumber());
        System.out.println("余额: $" + account.getBalance());
        
        account.deposit(500);
        System.out.println("存款后余额: $" + account.getBalance());
        
        boolean success = account.withdraw(200, "123456");
        System.out.println("取款" + (success ? "成功" : "失败"));
        System.out.println("取款后余额: $" + account.getBalance());
        
        // ❌ 错误:不能直接访问私有属性
        // System.out.println(account.balance);      // 编译错误
        // account.balance = 10000;                 // 编译错误
        // System.out.println(account.password);    // 编译错误
    }
}

2. 继承框架设计

java

csharp 复制代码
package framework;

// 框架基类
public abstract class BaseService {
    // 公共方法:对外接口
    public final void execute() {
        initialize();
        process();
        cleanup();
    }
    
    // 受保护方法:子类必须实现或可以重写
    protected abstract void initialize();
    protected abstract void process();
    
    // 受保护方法:子类可以重写
    protected void cleanup() {
        System.out.println("执行清理工作...");
    }
    
    // 私有方法:内部实现细节
    private void log(String message) {
        System.out.println("[LOG] " + message);
    }
    
    // 默认方法:同包的工具方法
    void internalHelper() {
        log("内部辅助方法");
    }
}

// 同包的工具类
package framework;

class ServiceValidator {
    // 默认方法:同包内使用
    static boolean validate(BaseService service) {
        // 可以访问 service.internalHelper()(同包)
        return true;
    }
}

java

typescript 复制代码
// 用户实现类(不同包)
package userapp;

import framework.BaseService;

public class UserService extends BaseService {
    // 实现抽象方法
    @Override
    protected void initialize() {
        System.out.println("用户服务初始化");
    }
    
    @Override
    protected void process() {
        System.out.println("处理用户请求");
    }
    
    // 可以重写 cleanup 方法
    @Override
    protected void cleanup() {
        super.cleanup();  // 调用父类方法
        System.out.println("额外的清理工作");
    }
    
    // 不能访问父类的私有方法
    // private void tryAccess() {
    //     log("测试");  // 编译错误:不能访问父类的private方法
    // }
    
    // 不能访问父类的默认方法(不同包)
    // void tryInternal() {
    //     internalHelper();  // 编译错误:不同包不能访问默认方法
    // }
    
    public static void main(String[] args) {
        UserService service = new UserService();
        service.execute();
    }
}

3. 常量定义

java

arduino 复制代码
// 常量类设计
public final class Constants {
    // 私有构造器:防止实例化
    private Constants() {
        throw new AssertionError("不能实例化常量类");
    }
    
    // 公共常量:所有地方可用
    public static final String APP_NAME = "MyApplication";
    public static final double PI = 3.141592653589793;
    public static final int MAX_RETRY_COUNT = 3;
    
    // 受保护常量:子类可用
    protected static final String DEFAULT_ENCODING = "UTF-8";
    
    // 默认常量:同包可用
    static final String CONFIG_FILE = "app.properties";
    
    // 私有常量:仅本类可用
    private static final String SECRET_KEY = "secret123";
    
    // 公共方法使用常量
    public static String getSecretHash() {
        return hash(SECRET_KEY);  // 可以访问私有常量
    }
    
    private static String hash(String input) {
        // 哈希计算
        return input + "_hashed";
    }
    
    // 同包辅助方法
    static String getConfigPath() {
        return CONFIG_FILE;  // 可以访问默认常量
    }
}

// 使用常量
public class ConstantUsage {
    public static void main(String[] args) {
        System.out.println("应用名称: " + Constants.APP_NAME);
        System.out.println("PI值: " + Constants.PI);
        System.out.println("最大重试次数: " + Constants.MAX_RETRY_COUNT);
        
        // 访问公共方法
        System.out.println("密钥哈希: " + Constants.getSecretHash());
        
        // ❌ 错误:不能访问受保护常量(不是子类)
        // System.out.println(Constants.DEFAULT_ENCODING);
        
        // ❌ 错误:不能访问默认常量(不同包)
        // System.out.println(Constants.CONFIG_FILE);
        
        // ❌ 错误:不能访问私有常量
        // System.out.println(Constants.SECRET_KEY);
    }
}

⚠️ 权限修饰符的注意事项

1. 类级别的访问控制

java

csharp 复制代码
// 公共类:所有地方可见(文件名必须与类名相同)
public class PublicClass {
    public void show() {
        System.out.println("公共类");
    }
}

// 默认类:同包可见
class DefaultClass {
    void show() {
        System.out.println("默认类");
    }
}

// 错误:一个文件只能有一个公共类,且必须与文件名相同
/*
public class AnotherPublicClass {  // 编译错误
}
*/

// 内部类可以是任何访问级别
class Outer {
    public class PublicInner {}
    protected class ProtectedInner {}
    class DefaultInner {}
    private class PrivateInner {}
}

// 测试
public class ClassLevelAccess {
    public static void main(String[] args) {
        PublicClass pc = new PublicClass();
        pc.show();
        
        // 同包可以访问默认类
        DefaultClass dc = new DefaultClass();
        dc.show();
        
        System.out.println("\n类访问规则:");
        System.out.println("1. 一个.java文件只能有一个public类");
        System.out.println("2. public类名必须与文件名相同");
        System.out.println("3. 可以有多个默认类");
        System.out.println("4. 内部类可以是任何访问级别");
    }
}

2. 接口成员的访问权限

java

csharp 复制代码
// 接口中的成员默认都是 public
public interface MyInterface {
    // 常量默认是 public static final
    String CONSTANT = "接口常量";  // 等价于 public static final
    
    // 方法默认是 public abstract
    void doSomething();  // 等价于 public abstract void doSomething()
    
    // Java 8+:默认方法
    default void defaultMethod() {
        System.out.println("默认方法");
    }
    
    // Java 8+:静态方法
    static void staticMethod() {
        System.out.println("静态方法");
    }
    
    // ❌ 错误:不能使用private(Java 9+可以)
    // private void privateMethod();  // Java 8编译错误
    
    // ❌ 错误:不能使用protected
    // protected void protectedMethod();  // 编译错误
}

// 实现接口
class MyImplementation implements MyInterface {
    // 必须使用public重写(不能更严格)
    @Override
    public void doSomething() {
        System.out.println("实现接口方法");
    }
    
    // 可以重写默认方法(可选)
    @Override
    public void defaultMethod() {
        MyInterface.super.defaultMethod();  // 调用接口的默认方法
        System.out.println("重写的默认方法");
    }
}

public class InterfaceAccess {
    public static void main(String[] args) {
        MyInterface.staticMethod();  // 调用接口静态方法
        
        MyImplementation impl = new MyImplementation();
        impl.doSomething();
        impl.defaultMethod();
        
        System.out.println("常量: " + MyInterface.CONSTANT);
    }
}

3. 构造器的访问权限

java

csharp 复制代码
public class ConstructorAccess {
    // 公共构造器:所有地方可以创建对象
    public ConstructorAccess() {
        System.out.println("公共构造器");
    }
    
    // 受保护构造器:同包或子类可以创建对象
    protected ConstructorAccess(int a) {
        System.out.println("受保护构造器: " + a);
    }
    
    // 默认构造器:同包可以创建对象
    ConstructorAccess(String s) {
        System.out.println("默认构造器: " + s);
    }
    
    // 私有构造器:只能在本类中创建对象
    private ConstructorAccess(boolean b) {
        System.out.println("私有构造器: " + b);
    }
    
    // 静态工厂方法访问私有构造器
    public static ConstructorAccess createPrivateInstance() {
        return new ConstructorAccess(true);
    }
    
    public static void main(String[] args) {
        // 本类中可以访问所有构造器
        new ConstructorAccess();           // public
        new ConstructorAccess(10);         // protected
        new ConstructorAccess("test");     // default
        new ConstructorAccess(true);       // private
        
        // 工厂方法
        ConstructorAccess.createPrivateInstance();
    }
}

// 同包的其他类
class SamePackageClass {
    void test() {
        new ConstructorAccess();           // ✅ public
        new ConstructorAccess(20);         // ✅ protected(同包)
        new ConstructorAccess("hello");    // ✅ default(同包)
        // new ConstructorAccess(true);    // ❌ private
    }
}

// 不同包子类
package other;

import ConstructorAccess;

class DifferentPackageChild extends ConstructorAccess {
    public DifferentPackageChild() {
        super(30);  // ✅ 可以调用protected构造器(子类)
        // super("test");  // ❌ 不能调用default构造器(不同包)
    }
    
    void test() {
        // new ConstructorAccess(40);  // ❌ 不能直接调用(需要是子类构造器中)
    }
}

// 不同包非子类
package other;

import ConstructorAccess;

class DifferentPackageNonChild {
    void test() {
        new ConstructorAccess();           // ✅ public
        // new ConstructorAccess(50);      // ❌ protected
        // new ConstructorAccess("test");  // ❌ default
        // new ConstructorAccess(true);    // ❌ private
    }
}

💡 权限修饰符最佳实践

1. 最小权限原则

java

typescript 复制代码
// 遵循最小权限原则:只暴露必要的内容
public class Employee {
    // 私有属性:隐藏实现细节
    private String id;
    private String name;
    private double salary;
    private String ssn;  // 社保号(敏感信息)
    
    // 公共构造器:允许创建对象
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
        this.salary = 0.0;
    }
    
    // 公共getter:只读访问
    public String getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
    public double getSalary() {
        return salary;
    }
    
    // 受保护setter:允许子类或同包修改
    protected void setSalary(double salary) {
        if (salary >= 0) {
            this.salary = salary;
        }
    }
    
    // 默认方法:同包工具方法
    void internalUpdate(String newName) {
        if (newName != null && newName.length() >= 2) {
            this.name = newName;
        }
    }
    
    // 私有方法:内部逻辑
    private void calculateBonus() {
        // 奖金计算逻辑
    }
    
    // 没有提供ssn的getter/setter(安全考虑)
}

// 管理者类(需要修改工资)
class Manager extends Employee {
    public Manager(String id, String name) {
        super(id, name);
    }
    
    public void adjustSalary(Employee emp, double newSalary) {
        // 可以调用受保护方法
        emp.setSalary(newSalary);
    }
}

2. 模块化设计

java

java 复制代码
// 包结构示例:
// com.company
//   ├── api          (公共API)
//   ├── impl         (实现,包私有)
//   ├── internal     (内部实现,包私有)
//   └── util         (工具类)

// api包:公共接口
package com.company.api;

public interface UserService {
    User getUser(String id);
    void saveUser(User user);
}

// impl包:实现(包私有)
package com.company.impl;

import com.company.api.UserService;
import com.company.internal.UserValidator;

class UserServiceImpl implements UserService {
    private UserValidator validator = new UserValidator();
    
    @Override
    public User getUser(String id) {
        // 实现...
        return null;
    }
    
    @Override
    public void saveUser(User user) {
        if (validator.validate(user)) {
            // 保存逻辑
        }
    }
}

// internal包:内部工具(包私有)
package com.company.internal;

class UserValidator {
    boolean validate(User user) {
        // 验证逻辑
        return true;
    }
}

// 公共工厂
package com.company;

import com.company.api.UserService;
import com.company.impl.UserServiceImpl;

public class ServiceFactory {
    // 公共方法返回接口类型,隐藏实现
    public static UserService createUserService() {
        return new UserServiceImpl();
    }
}

📊 权限修饰符选择指南

选择流程图

text

arduino 复制代码
开始
  ↓
需要从外部访问吗?
  ├─ 否 → 使用 private
  ↓
需要被子类访问吗?
  ├─ 否 → 需要同包访问吗?
  │      ├─ 是 → 使用 默认
  │      ↓
  │     否 → 使用 public
  ↓
是 → 需要不同包子类访问吗?
        ├─ 是 → 使用 protected
        ↓
       否 → 使用 默认

决策表格

场景 推荐修饰符 示例
数据字段 private private String name;
常量 public static final public static final PI = 3.14;
工具方法 private private void validate()
模板方法 protected protected void initialize()
接口方法 public public void save()
构造器 public / private public User() / 单例模式
内部类 private private class Node
测试钩子 protected protected void setUp()

🎓 总结要点

  1. private:严格封装,仅本类可见
  2. 默认:包级别封装,同包可见
  3. protected:继承友好,同包+子类可见
  4. public:完全开放,所有地方可见

核心原则

  • 最小权限原则:只开放必要的访问权限
  • 封装变化:使用private隐藏实现细节
  • 面向接口:通过public方法提供稳定接口
  • 继承设计:protected用于设计可扩展的框架
  • 包组织:合理使用包和默认权限管理模块

记住:良好的访问控制是高质量代码的基础!合理的权限设置可以提高代码的安全性、可维护性和可扩展性。

相关推荐
晨非辰1 小时前
算法闯关日记 Episode :解锁链表「环形」迷局与「相交」奥秘
数据结构·c++·人工智能·后端·python·深度学习·神经网络
00后程序员1 小时前
iOS 上架 4.3,重复 App 审核条款的真实逻辑与团队应对策略研究
后端
00后程序员1 小时前
专业的 IPA 处理工具 构建可维护、可回滚的 iOS 成品加工与加固流水线
后端
百度Geek说1 小时前
项目级效能提升一站式交付最佳实践
后端
今天你TLE了吗1 小时前
通过RocketMQ延时消息实现优惠券等业务MySQL当中定时自动过期
java·spring boot·后端·学习·rocketmq
Gundy1 小时前
构建一个真正好用的简单搜索引擎
后端
疯狂的程序猴2 小时前
构建面向复杂场景的 iOS 应用测试体系 多工具协同下的高质量交付实践
后端
大巨头2 小时前
C# 中如何理解泛型
后端
用户992441031562 小时前
TRAE SOLO实战录:AI应用可观测性与风险管控的破局之道
后端