Java访问修饰符详解全面掌握public、private、protected和默认修饰符访问修饰符概述修饰类的规则顶级类非内部类内部类嵌套类修饰成员变量⭐同一包中访问级别对比不同包中的访问修饰方法普通方法方法重写的访问规则修饰构造函数修饰接口成员最佳实践总结选择原则常用场景在Java中访问修饰符Access Modifiers是控制类、方法、变量和构造函数的可见性和访问权限的关键工具。合理使用访问修饰符是实现封装、提高代码安全性和可维护性的基础。本文将全面解析四种访问修饰符的使用规则和最佳实践。访问修饰符概述Java提供了四种访问级别从严格到开放依次为修饰符本类内部同一包内不同包子类不同包非子类private✓✗✗✗默认无修饰符✓✓✗✗protected✓✓✓✗public✓✓✓✓修饰类的规则顶级类非内部类顶级类只能使用public或默认修饰符// 正确示例publicclassPublicClass{}// 任何地方都可以访问classDefaultClass{}// 同一包内可以访问// 错误示例// private class PrivateClass { } // 编译错误// protected class ProtectedClass { } // 编译错误内部类嵌套类内部类可以使用所有四种访问修饰符publicclassOuterClass{publicclassPublicInner{}protectedclassProtectedInner{}privateclassPrivateInner{}// 只能在OuterClass内部访问classDefaultInner{}}修饰成员变量⭐同一包中访问级别对比publicclassVariableExample{publicintpublicVar;// 任何地方可访问protectedintprotectedVar;// 同一包内和子类可访问intdefaultVar;// 同一包内可访问privateintprivateVar;// 仅本类可访问publicvoidtestAccess(){this.publicVar1;// ✓ 可访问this.protectedVar2;// ✓ 可访问this.defaultVar3;// ✓ 可访问this.privateVar4;// ✓ 可访问}}不同包中的访问// 在不同包的子类中publicclassSubClassextendsVariableExample{publicvoidaccessInSubclass(){publicVar1;// ✓ 可访问protectedVar2;// ✓ 可访问通过继承// defaultVar 3; // ✗ 编译错误不同包// privateVar 4; // ✗ 编译错误}}// 在不同包的非子类中publicclassOtherClass{publicvoidaccessInOther(){VariableExampleexamplenewVariableExample();example.publicVar1;// ✓ 可访问// example.protectedVar 2; // ✗ 编译错误// example.defaultVar 3; // ✗ 编译错误// example.privateVar 4; // ✗ 编译错误}}修饰方法普通方法publicclassMethodExample{publicvoidpublicMethod(){}protectedvoidprotectedMethod(){}voiddefaultMethod(){}privatevoidprivateMethod(){}// 调用本类方法publicvoidcallAllMethods(){publicMethod();// ✓protectedMethod();// ✓defaultMethod();// ✓privateMethod();// ✓}}方法重写的访问规则重写方法的访问级别不能比原方法更严格publicclassParent{publicvoidpublicMethod(){}protectedvoidprotectedMethod(){}voiddefaultMethod(){}}classChildextendsParent{OverridepublicvoidpublicMethod(){}// ✓ 可以保持publicOverrideprotectedvoidprotectedMethod(){}// ✓ 可以保持protectedOverridepublicvoidprotectedMethod(){}// ✓ 可以提升为public// Override// private void protectedMethod() { } // ✗ 编译错误不能降级为privateOverridevoiddefaultMethod(){}// ✓ 在同一包中可以}修饰构造函数packageuniversity;// 学生类 - 展示各种访问级别的构造函数publicclassStudent{privateStringid;privateStringname;privateStringmajor;// 1. public构造函数 - 任何人都能创建普通学生publicStudent(Stringname){this.idgenerateId();this.namename;this.major未定;System.out.println(新生入学name);}// 2. protected构造函数 - 专门给子类研究生使用protectedStudent(Stringname,Stringmajor){this.idgenerateId();this.namename;this.majormajor;System.out.println(研究生入学name专业major);}// 3. 默认构造函数 - 只能在本包内使用用于快速创建测试对象Student(Stringname,Stringid,Stringmajor){this.idid;this.namename;this.majormajor;System.out.println(内部使用学生name);}// 4. private构造函数 - 只在类内部使用用于特殊初始化privateStudent(){this.id000000;this.name系统保留;this.major管理员;System.out.println(系统内部创建管理员学生);}// 静态工厂方法 - 外部通过这个获取特殊实例publicstaticStudentcreateAdminStudent(){returnnewStudent();// 调用private构造函数}privateStringgenerateId(){returnSSystem.currentTimeMillis();}publicvoidshowInfo(){System.out.println(学号id姓名name专业major);}}packageuniversity;// 研究生类 - 继承StudentpublicclassGraduateStudentextendsStudent{publicGraduateStudent(Stringname,Stringmajor){super(name,major);// 调用父类的protected构造函数 ✅System.out.println(研究生详细信息已创建);}}packageuniversity;// 测试类 - 同一个包内publicclassTestSamePackage{publicstaticvoidmain(String[]args){// 测试public构造函数Students1newStudent(张三);// ✅ 可以s1.showInfo();// 测试protected构造函数注意在同一个包内也可以直接调用protectedStudents2newStudent(李四,计算机);// ✅ 可以在同一包内调用protecteds2.showInfo();// 测试默认构造函数Students3newStudent(王五,S001,数学);// ✅ 可以同一包内s3.showInfo();// 测试private构造函数不能直接调用// Student s4 new Student(); // ❌ 编译错误// 通过静态方法获取private构造的对象Students4Student.createAdminStudent();// ✅ 可以s4.showInfo();// 测试子类GraduateStudentgsnewGraduateStudent(赵六,物理);// ✅ 可以gs.showInfo();}}packagecompany;// 不同包importuniversity.Student;publicclassTestDifferentPackage{publicstaticvoidmain(String[]args){// public构造函数 - 任何地方都能用Students1newStudent(小明);// ✅ 可以s1.showInfo();// protected构造函数 - 在不同包的非子类中不能调用// Student s2 new Student(小红, 英语); // ❌ 编译错误// 默认构造函数 - 在不同包中不能调用// Student s3 new Student(小刚, S002, 化学); // ❌ 编译错误// private构造函数 - 只能通过静态方法Students4Student.createAdminStudent();// ✅ 可以静态方法是publics4.showInfo();}}构造函数修饰符使用场景典型例子public普通的、任何人都能创建的类DTO、实体类、工具类protected抽象类、基类主要给子类用框架中的基类默认包内协作不对外公开的类内部实现类、辅助类private严格控制创建方式单例、工厂模式、工具类修饰接口成员接口成员有特殊的访问规则publicinterfaceMyInterface{// 接口中的变量默认是 public static finalintPUBLIC_CONSTANT100;// 实际上是 public static final// 接口中的方法默认是 public abstractvoidpublicMethod();// 实际上是 public abstract// Java 9 可以有private方法privatevoidprivateMethod(){System.out.println(Private method in interface);}// default方法默认是publicdefaultvoiddefaultMethod(){privateMethod();// 可以调用private方法}}最佳实践总结选择原则最小权限原则尽可能使用最严格的访问级别封装性将实现细节隐藏起来只暴露必要的API常用场景场景推荐修饰符原因API公开方法public需要对外提供服务工具类常量public需要全局访问内部实现细节private隐藏实现便于修改子类需要的方法protected平衡封装和继承同一包协作的类默认包级封装publicclassBankAccount{// 私有成员变量 - 封装数据privateStringaccountNumber;privatedoublebalance;// 公共构造函数publicBankAccount(StringaccountNumber){this.accountNumberaccountNumber;this.balance0;}// 公共APIpublicvoiddeposit(doubleamount){if(amount0){balanceamount;logTransaction(Deposit,amount);// 调用私有方法}}publicdoublegetBalance(){returnbalance;}// 保护方法 - 子类可以扩展protectedvoidlogTransaction(Stringtype,doubleamount){System.out.println(type: $amount);}// 私有方法 - 内部实现privatebooleanvalidateAmount(doubleamount){returnamount0amount10000;}}