理解 Java 中四种访问修饰符的作用与区别
掌握 private、默认(包私有)、protected 和 public 的使用场景
能够在实际项目中合理运用访问控制以增强封装性和安全性
在 Java 中,访问修饰符是用于控制类、方法、变量等成员可见性范围的关键字。它们决定了程序的其他部分能否访问某个特定成员,是实现封装的核心机制之一。

Java 提供了 4 种访问修饰符:
private
默认(即不写任何修饰符,也称为“包私有”)
protected
public
关键字:private
作用范围:仅限于声明它的类内部
特点:最严格的访问限制,外部类、子类、甚至同包中的其他类都无法直接访问
class Person {
// 私有变量
private String name;
public void setName(String name) {
this.name = name; // 类内部可访问
}
public String getName() {
return name; // 类内部可访问
}
}
public class MainApp {
public static void main(String[] args) {
Person p = new Person();
p.setName("Alice");
// System.out.println(p.name); // 编译错误:'name' 具有私有访问权限
System.out.println(p.getName()); // 通过公共方法间接访问
}
}输出:
Alice说明:
name字段被设为private,强制外部通过setName()和getName()方法操作数据,这体现了面向对象编程中的数据封装原则。
默认访问修饰符(包私有)
关键字:无(即不写任何修饰符)
作用范围:同一个包内的所有类均可访问
注意:跨包不可见,即使通过继承也不行
示例:同包访问
// 文件:Car.java(位于默认包或同一命名包中)
class Car {
String model; // 默认访问权限
}
// 文件:Main.java
public class Main {
public static void main(String[] args) {
Car c = new Car();
c.model = "Tesla"; // 同包内可访问
System.out.println(c.model);
}
}输出:
Tesla跨包访问失败示例
文件:p1/Tool.java
package p1;
class Tool { // 默认访问修饰符
void use() {
System.out.println("Using tool");
}
}文件:p2/App.java
package p2;
import p1.*;
class App {
public static void main(String[] args) {
Tool t = new Tool(); // ❌ 编译错误!Tool 在 p1 包中是默认访问,p2 无法访问
t.use();
}
}结论:默认修饰符适用于仅在当前包内使用的工具类或辅助方法。
关键字:protected
作用范围:
同一个包内的所有类
不同包中的子类(通过继承)
注意:不同包中的非子类不能访问
class Vehicle {
protected int speed; // 受保护成员
}
class Bike extends Vehicle {
void setSpeed(int s) {
speed = s; // 子类中可访问
}
int getSpeed() {
return speed; // 子类中可访问
}
}
public class Main {
public static void main(String[] args) {
Bike b = new Bike();
b.setSpeed(100);
System.out.println("通过子类方法访问: " + b.getSpeed());
Vehicle v = new Vehicle();
System.out.println(v.speed); // 同包内直接访问(假设 Main 与 Vehicle 同包)
}
}输出:
通过子类方法访问: 100
0关键点:
protected常用于框架设计中,允许用户通过继承扩展功能,同时限制非继承类的随意访问。
关键字:public
作用范围:整个程序中任意位置均可访问
用途:公开 API、服务类、工具方法等
class MathUtils {
public static int add(int a, int b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
System.out.println(MathUtils.add(5, 10)); // 任何地方都能调用
}
}输出:
15注意:顶层类(Top-level class)不能声明为
private或protected,只能是public或默认(包私有)。因为private意味着“仅在封闭类中可见”,而顶层类没有外层类。
最佳实践:最小权限原则 —— 总是使用尽可能严格的访问级别。先设为
private,只有在确实需要更广访问时才逐步放宽。
Java 有 4 种访问修饰符:private、默认、protected、public
private 最严格,仅限本类;public 最开放,全局可见
默认修饰符 = 包内可见,常被忽略但非常实用
protected = 包内 + 子类可见,是继承体系中的桥梁
顶层类不能是 private 或 protected
合理使用访问修饰符是构建高内聚、低耦合系统的关键
为什么 Java 不允许将顶层类声明为 private?请从语言设计角度解释。
在一个多人协作的大型项目中,如果所有字段都设为 public,会带来哪些潜在风险?
假设你正在开发一个日志框架,希望用户能继承你的 BaseLogger 类并重写 formatMessage() 方法,但不希望他们直接调用该方法。你会如何设计其访问修饰符?