Java的访问修饰符是面向对象编程中封装特性的重要实现手段,通过限制类、接口、方法、变量的可访问范围,既保护了内部实现细节,也规范了不同模块之间的交互方式。合理使用访问修饰符能够让代码结构更清晰,降低模块间的耦合度。

Java的四种访问修饰符分类
Java提供了四种不同权限的访问修饰符,按照权限从低到高依次为private、默认(无修饰符)、protected、public,每种修饰符的适用场景和访问范围都有明确区别。
1. private修饰符
private是权限最低的修饰符,被它修饰的成员只能在当前类的内部被访问,外部类、子类都无法直接访问。它通常用于隐藏类的内部实现细节,比如类的私有属性、内部辅助方法等。
public class User {
// 私有属性,只能在User类内部访问
private String username;
private int age;
// 私有方法,仅内部使用
private void validateAge() {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
// 对外提供的公共方法,用于设置年龄
public void setAge(int age) {
this.age = age;
validateAge(); // 内部调用私有方法
}
public int getAge() {
return age;
}
}
2. 默认修饰符(无修饰符)
如果不写任何访问修饰符,就是默认访问权限,也叫包访问权限。被默认修饰符修饰的成员,只能被同一个包下的其他类访问,不同包的类无法访问,即使是子类也不行。
// 当前类在com.example.demo包下
package com.example.demo;
class DefaultAccessClass {
// 默认访问权限的属性
String defaultField = "默认权限字段";
// 默认访问权限的方法
void defaultMethod() {
System.out.println("默认权限方法");
}
}
// 同一个包下的其他类可以访问
package com.example.demo;
public class Test {
public static void main(String[] args) {
DefaultAccessClass obj = new DefaultAccessClass();
System.out.println(obj.defaultField); // 可以正常访问
obj.defaultMethod(); // 可以正常调用
}
}
3. protected修饰符
protected修饰的成员,除了可以被同一个包下的其他类访问之外,还可以被不同包下的子类访问。它通常用于父类向子类暴露部分可扩展的实现,同时限制非子类的外部类访问。
// 父类在com.example.parent包下
package com.example.parent;
public class Parent {
protected String protectedField = "受保护字段";
protected void protectedMethod() {
System.out.println("受保护方法");
}
}
// 子类在com.example.child包下,不同包
package com.example.child;
import com.example.parent.Parent;
public class Child extends Parent {
public void test() {
System.out.println(protectedField); // 子类可以访问父类的protected成员
protectedMethod(); // 子类可以调用父类的protected方法
}
}
4. public修饰符
public是权限最高的修饰符,被它修饰的成员可以被任意包下的任意类访问,没有访问范围限制。通常用于对外提供的公共接口、工具类的公共方法等场景。
package com.example.util;
public class MathUtil {
// 公共静态方法,任意类都可以调用
public static int add(int a, int b) {
return a + b;
}
}
// 其他包的类调用
package com.example.test;
import com.example.util.MathUtil;
public class Test {
public static void main(String[] args) {
int result = MathUtil.add(1, 2); // 可以正常调用
System.out.println(result);
}
}
访问修饰符对可见性的影响
访问修饰符的核心作用就是控制成员的可见性,不同修饰符对应的可见范围可以通过下表清晰对比:
| 修饰符 | 同一类中 | 同一包中 | 不同包的子类 | 不同包的非子类 |
|---|---|---|---|---|
| private | 可见 | 不可见 | 不可见 | 不可见 |
| 默认 | 可见 | 可见 | 不可见 | 不可见 |
| protected | 可见 | 可见 | 可见 | 不可见 |
| public | 可见 | 可见 | 可见 | 可见 |
可见性的控制直接关系到代码的安全性,比如将类的核心属性设置为private,可以避免外部随意修改属性值,只能通过类提供的公共方法来操作,保证属性的合法性。
访问修饰符对封装边界的影响
封装的核心思想是隐藏内部实现细节,只对外暴露必要的接口,访问修饰符就是划定封装边界的关键工具。合理的封装边界能够降低代码的耦合度,提高代码的可维护性。
通常来说,类的属性应该尽可能设置为private,如果需要让外部获取或修改属性,可以提供public的getter和setter方法,在方法中可以添加必要的校验逻辑,这就是典型的封装实践。
public class Student {
private String name;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("姓名不能为空");
}
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("分数必须在0到100之间");
}
this.score = score;
}
}
对于类内部的辅助方法,不需要对外暴露的应该设置为private或者默认权限,避免外部类误调用。如果某个方法需要让子类重写扩展,但是不希望被其他外部类调用,可以设置为protected,这样既能保证封装性,又能给子类留出扩展空间。
访问修饰符的使用建议
在实际开发中,选择访问修饰符可以遵循最小权限原则:即尽可能使用权限最低的修饰符,只有当更低权限无法满足需求时,再提升权限。这样能够最大程度地保护代码的内部实现,减少不必要的外部依赖。
- 类的属性优先使用
private,通过公共方法暴露访问接口 - 仅内部使用的辅助方法使用
private或者默认权限 - 需要被子类重写的方法使用
protected - 对外提供的公共接口、工具类方法使用
public - 非公共的类尽量使用默认权限,避免被其他包的类随意引用
遵循这些原则,能够让代码的封装边界更清晰,后续的修改和维护也会更方便,不会因为权限设置过宽导致修改内部实现时影响大量外部调用代码。