Java 类级成员修饰符详解
·
一、四大访问权限修饰符(控制可见范围)
Java 一共有 4 个访问修饰符,用来限制类的成员(变量、方法)在不同位置能否被访问,权限范围从大到小排序:
1. public(公共的)
- 修饰范围:可以修饰类、成员变量、成员方法。
- 访问权限:任何包、任何类中都能直接访问。
- 特点:权限最大,无访问限制。
- 使用场景:对外提供的接口方法、需要全局访问的成员。
// 示例:public 修饰符在不同包/子类中的访问情况
// com.example.package1
package com.example.package1;
public class PublicExample {
public String publicField = "公共字段";
public void publicMethod() {
System.out.println("公共方法");
}
}
// com.example.package2
package com.example.package2;
import com.example.package1.PublicExample;
public class TestPublic {
public void test() {
PublicExample example = new PublicExample();
System.out.println(example.publicField); // ✅ 可以访问
example.publicMethod(); // ✅ 可以访问
}
}
// com.example.package2 的子类
package com.example.package2;
import com.example.package1.PublicExample;
public class SubClass extends PublicExample {
public void test() {
System.out.println(publicField); // ✅ 可以访问(继承)
publicMethod(); // ✅ 可以访问(继承)
}
}
2. protected(受保护的)
- 修饰范围:只能修饰成员变量、成员方法,不能修饰普通类。
- 访问权限:
- 本类内部可以访问。
- 同一个包下的类可以访问。
- 不同包的子类可以继承访问。
- 使用场景:希望子类继承、但不想对外公开的成员。
// 示例:protected 修饰符在不同包/子类中的访问情况
// com.example.package1
package com.example.package1;
public class ProtectedExample {
protected String protectedField = "受保护字段";
protected void protectedMethod() {
System.out.println("受保护方法");
}
public void testInSameClass() {
System.out.println(protectedField); // ✅ 本类可以访问
protectedMethod(); // ✅ 本类可以访问
}
}
// com.example.package1 的同包类
package com.example.package1;
public class SamePackageClass {
public void test() {
ProtectedExample example = new ProtectedExample();
System.out.println(example.protectedField); // ✅ 同包类可以访问
example.protectedMethod(); // ✅ 同包类可以访问
}
}
// com.example.package2 的子类
package com.example.package2;
import com.example.package1.ProtectedExample;
public class SubClass extends ProtectedExample {
public void test() {
System.out.println(protectedField); // ✅ 不同包子类可以访问(继承)
protectedMethod(); // ✅ 不同包子类可以访问(继承)
}
}
// com.example.package2 的非子类(无法访问)
package com.example.package2;
import com.example.package1.ProtectedExample;
public class OtherPackageClass {
public void test() {
ProtectedExample example = new ProtectedExample();
// System.out.println(example.protectedField); // ❌ 编译错误:不同包非子类不能访问
// example.protectedMethod(); // ❌ 编译错误:不同包非子类不能访问
}
}
3. 默认权限(缺省 / 包访问权限)
- 写法:不写任何修饰符。
- 访问权限:只有同一个包内的类可以访问,跨包无论是否是子类都无法访问。
- 特点:介于 protected 和 private 之间,日常开发很少主动使用。
// 示例:默认权限在不同包/子类中的访问情况
// com.example.package1
package com.example.package1;
public class DefaultExample {
String defaultField = "默认权限字段"; // 没有修饰符,即默认权限
void defaultMethod() {
System.out.println("默认权限方法");
}
public void testInSameClass() {
System.out.println(defaultField); // ✅ 本类可以访问
defaultMethod(); // ✅ 本类可以访问
}
}
// com.example.package1 的同包类
package com.example.package1;
public class SamePackageClass {
public void test() {
DefaultExample example = new DefaultExample();
System.out.println(example.defaultField); // ✅ 同包类可以访问
example.defaultMethod(); // ✅ 同包类可以访问
}
}
// com.example.package2 的子类(无法访问)
package com.example.package2;
import com.example.package1.DefaultExample;
public class SubClass extends DefaultExample {
public void test() {
// System.out.println(defaultField); // ❌ 编译错误:不同包子类不能访问默认权限成员
// defaultMethod(); // ❌ 编译错误:不同包子类不能访问默认权限方法
}
}
// com.example.package2 的非子类(无法访问)
package com.example.package2;
import com.example.package1.DefaultExample;
public class OtherPackageClass {
public void test() {
DefaultExample example = new DefaultExample();
// System.out.println(example.defaultField); // ❌ 编译错误:不同包类不能访问
// example.defaultMethod(); // ❌ 编译错误:不同包类不能访问
}
}
4. private(私有的)
- 修饰范围:只能修饰成员变量、成员方法,不能修饰类。
- 访问权限:仅当前类内部可以访问,子类、同包类、外部类全都不能直接访问。
- 使用场景:封装成员变量,配合 get/set 方法取值赋值,是 Java 封装思想的核心。
// 示例:private 修饰符在不同包/子类中的访问情况
// com.example.package1
package com.example.package1;
public class PrivateExample {
private String privateField = "私有字段";
private void privateMethod() {
System.out.println("私有方法");
}
// 提供公共访问方法(封装)
public String getPrivateField() {
return privateField;
}
public void setPrivateField(String value) {
this.privateField = value;
}
public void callPrivateMethod() {
privateMethod(); // ✅ 本类可以访问私有方法
}
public void testInSameClass() {
System.out.println(privateField); // ✅ 本类可以访问
privateMethod(); // ✅ 本类可以访问
}
}
// com.example.package1 的同包类(无法访问)
package com.example.package1;
public class SamePackageClass {
public void test() {
PrivateExample example = new PrivateExample();
// System.out.println(example.privateField); // ❌ 编译错误:同包类不能访问私有成员
// example.privateMethod(); // ❌ 编译错误:同包类不能访问私有方法
// 只能通过公共方法访问
System.out.println(example.getPrivateField()); // ✅ 通过getter访问
example.callPrivateMethod(); // ✅ 通过公共方法间接调用私有方法
}
}
// com.example.package2 的子类(无法访问)
package com.example.package2;
import com.example.package1.PrivateExample;
public class SubClass extends PrivateExample {
public void test() {
// System.out.println(privateField); // ❌ 编译错误:子类不能访问父类私有成员
// privateMethod(); // ❌ 编译错误:子类不能访问父类私有方法
// 只能通过继承的公共方法访问
System.out.println(getPrivateField()); // ✅ 通过继承的getter访问
callPrivateMethod(); // ✅ 通过继承的公共方法间接调用
}
}
// com.example.package2 的非子类(无法访问)
package com.example.package2;
import com.example.package1.PrivateExample;
public class OtherPackageClass {
public void test() {
PrivateExample example = new PrivateExample();
// System.out.println(example.privateField); // ❌ 编译错误:外部类不能访问
// example.privateMethod(); // ❌ 编译错误:外部类不能访问
// 只能通过公共方法访问
System.out.println(example.getPrivateField()); // ✅ 通过公共getter访问
example.callPrivateMethod(); // ✅ 通过公共方法间接调用
}
}
访问权限范围对照表
| 修饰符 | 本类 | 同包类 | 不同包子类 | 任意外部类 |
|---|---|---|---|---|
| public | ✅ | ✅ | ✅ | ✅ |
| protected | ✅ | ✅ | ✅ | ❌ |
| 默认(缺省) | ✅ | ✅ | ❌ | ❌ |
| private | ✅ | ❌ | ❌ | ❌ |
二、非访问修饰符(不控制权限,修改特性)
1. static(静态修饰符)
- 修饰成员变量:
- 变成静态变量(类变量),不属于对象,属于整个类。
- 内存只加载一次,所有对象共享同一份数据。
- 调用方式:
类名.变量名(推荐)、对象名.变量名。
- 修饰成员方法:
- 变成静态方法(类方法),可以直接用类名调用。
- 静态方法不能直接访问非静态成员变量、非静态方法,因为静态优先加载,此时对象还未创建。
- 静态方法中不能使用
this、super关键字。
- 使用场景:工具方法、全局共享常量、计数变量。
2. final(最终修饰符)
- 修饰成员变量:
- 变量变成常量,赋值后无法修改。
- 成员常量必须手动初始化:要么定义时直接赋值,要么在构造方法中赋值。
- 修饰成员方法:
- 方法不能被子类重写(覆写)。
- 修饰类:
- 类不能被继承。
3. abstract(抽象修饰符)
- 只能修饰方法和类,不能修饰变量。
- 修饰方法:抽象方法,只有方法声明,没有方法体,必须放在抽象类中。
- 修饰类:抽象类,不能
new创建对象,用来被子类继承,强制子类实现抽象方法。
⚠️ 注意:abstract 和 final 不能同时修饰一个方法,抽象方法需要子类重写,final 禁止重写,二者矛盾。
4. transient(瞬态修饰符)
- 仅修饰成员变量。
- 作用:Java 序列化时,被
transient修饰的变量不会被保存到文件中。
5. volatile(易变修饰符)
- 仅修饰成员变量,多线程并发编程使用。
- 作用:保证变量在多线程下的可见性,禁止指令重排序。
6. synchronized(同步修饰符)
- 仅修饰方法。
- 作用:多线程环境下给方法加锁,保证同一时间只有一个线程执行该方法,解决线程安全问题。
三、修饰符组合使用规则(高频考点)
private、protected、public三者不能同时出现两个。abstract不能和final、private、static一起修饰方法。static方法不能使用this、super。- 普通成员方法可以访问静态成员,但静态方法不能访问普通成员。
- 类上面只能使用
public、abstract、final三个修饰符。
四、总结区分
- 访问修饰符(
public/protected/默认/private):管「能不能访问」。 static:管「属于类还是对象」。final:管「能不能修改、重写、继承」。abstract:管「是否需要子类实现」。transient/volatile/synchronized:多用于 IO、多线程高级场景。
更多推荐


所有评论(0)