
一、四大访问权限修饰符控制可见范围Java 一共有 4 个访问修饰符用来限制类的成员变量、方法在不同位置能否被访问权限范围从大到小排序1. public公共的修饰范围可以修饰类、成员变量、成员方法。访问权限任何包、任何类中都能直接访问。特点权限最大无访问限制。使用场景对外提供的接口方法、需要全局访问的成员。// 示例public 修饰符在不同包/子类中的访问情况// com.example.package1packagecom.example.package1;publicclassPublicExample{publicStringpublicField公共字段;publicvoidpublicMethod(){System.out.println(公共方法);}}// com.example.package2packagecom.example.package2;importcom.example.package1.PublicExample;publicclassTestPublic{publicvoidtest(){PublicExampleexamplenewPublicExample();System.out.println(example.publicField);// ✅ 可以访问example.publicMethod();// ✅ 可以访问}}// com.example.package2 的子类packagecom.example.package2;importcom.example.package1.PublicExample;publicclassSubClassextendsPublicExample{publicvoidtest(){System.out.println(publicField);// ✅ 可以访问继承publicMethod();// ✅ 可以访问继承}}2. protected受保护的修饰范围只能修饰成员变量、成员方法不能修饰普通类。访问权限本类内部可以访问。同一个包下的类可以访问。不同包的子类可以继承访问。使用场景希望子类继承、但不想对外公开的成员。// 示例protected 修饰符在不同包/子类中的访问情况// com.example.package1packagecom.example.package1;publicclassProtectedExample{protectedStringprotectedField受保护字段;protectedvoidprotectedMethod(){System.out.println(受保护方法);}publicvoidtestInSameClass(){System.out.println(protectedField);// ✅ 本类可以访问protectedMethod();// ✅ 本类可以访问}}// com.example.package1 的同包类packagecom.example.package1;publicclassSamePackageClass{publicvoidtest(){ProtectedExampleexamplenewProtectedExample();System.out.println(example.protectedField);// ✅ 同包类可以访问example.protectedMethod();// ✅ 同包类可以访问}}// com.example.package2 的子类packagecom.example.package2;importcom.example.package1.ProtectedExample;publicclassSubClassextendsProtectedExample{publicvoidtest(){System.out.println(protectedField);// ✅ 不同包子类可以访问继承protectedMethod();// ✅ 不同包子类可以访问继承}}// com.example.package2 的非子类无法访问packagecom.example.package2;importcom.example.package1.ProtectedExample;publicclassOtherPackageClass{publicvoidtest(){ProtectedExampleexamplenewProtectedExample();// System.out.println(example.protectedField); // ❌ 编译错误不同包非子类不能访问// example.protectedMethod(); // ❌ 编译错误不同包非子类不能访问}}3. 默认权限缺省 / 包访问权限写法不写任何修饰符。访问权限只有同一个包内的类可以访问跨包无论是否是子类都无法访问。特点介于 protected 和 private 之间日常开发很少主动使用。// 示例默认权限在不同包/子类中的访问情况// com.example.package1packagecom.example.package1;publicclassDefaultExample{StringdefaultField默认权限字段;// 没有修饰符即默认权限voiddefaultMethod(){System.out.println(默认权限方法);}publicvoidtestInSameClass(){System.out.println(defaultField);// ✅ 本类可以访问defaultMethod();// ✅ 本类可以访问}}// com.example.package1 的同包类packagecom.example.package1;publicclassSamePackageClass{publicvoidtest(){DefaultExampleexamplenewDefaultExample();System.out.println(example.defaultField);// ✅ 同包类可以访问example.defaultMethod();// ✅ 同包类可以访问}}// com.example.package2 的子类无法访问packagecom.example.package2;importcom.example.package1.DefaultExample;publicclassSubClassextendsDefaultExample{publicvoidtest(){// System.out.println(defaultField); // ❌ 编译错误不同包子类不能访问默认权限成员// defaultMethod(); // ❌ 编译错误不同包子类不能访问默认权限方法}}// com.example.package2 的非子类无法访问packagecom.example.package2;importcom.example.package1.DefaultExample;publicclassOtherPackageClass{publicvoidtest(){DefaultExampleexamplenewDefaultExample();// System.out.println(example.defaultField); // ❌ 编译错误不同包类不能访问// example.defaultMethod(); // ❌ 编译错误不同包类不能访问}}4. private私有的修饰范围只能修饰成员变量、成员方法不能修饰类。访问权限仅当前类内部可以访问子类、同包类、外部类全都不能直接访问。使用场景封装成员变量配合 get/set 方法取值赋值是 Java 封装思想的核心。// 示例private 修饰符在不同包/子类中的访问情况// com.example.package1packagecom.example.package1;publicclassPrivateExample{privateStringprivateField私有字段;privatevoidprivateMethod(){System.out.println(私有方法);}// 提供公共访问方法封装publicStringgetPrivateField(){returnprivateField;}publicvoidsetPrivateField(Stringvalue){this.privateFieldvalue;}publicvoidcallPrivateMethod(){privateMethod();// ✅ 本类可以访问私有方法}publicvoidtestInSameClass(){System.out.println(privateField);// ✅ 本类可以访问privateMethod();// ✅ 本类可以访问}}// com.example.package1 的同包类无法访问packagecom.example.package1;publicclassSamePackageClass{publicvoidtest(){PrivateExampleexamplenewPrivateExample();// System.out.println(example.privateField); // ❌ 编译错误同包类不能访问私有成员// example.privateMethod(); // ❌ 编译错误同包类不能访问私有方法// 只能通过公共方法访问System.out.println(example.getPrivateField());// ✅ 通过getter访问example.callPrivateMethod();// ✅ 通过公共方法间接调用私有方法}}// com.example.package2 的子类无法访问packagecom.example.package2;importcom.example.package1.PrivateExample;publicclassSubClassextendsPrivateExample{publicvoidtest(){// System.out.println(privateField); // ❌ 编译错误子类不能访问父类私有成员// privateMethod(); // ❌ 编译错误子类不能访问父类私有方法// 只能通过继承的公共方法访问System.out.println(getPrivateField());// ✅ 通过继承的getter访问callPrivateMethod();// ✅ 通过继承的公共方法间接调用}}// com.example.package2 的非子类无法访问packagecom.example.package2;importcom.example.package1.PrivateExample;publicclassOtherPackageClass{publicvoidtest(){PrivateExampleexamplenewPrivateExample();// 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、多线程高级场景。