首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >访问权限

访问权限

原创
作者头像
用户11708420
修改2025-06-22 11:31:32
修改2025-06-22 11:31:32
3720
举报

一、包访问权限

判断是否为同一个包的核心规则

  • 包名完全一致才是同一个包:必须每个层级的名称都相同(包括大小写)。
  • 子包与父包的区别:子包(如 com.User.abc)是父包(com.User)的下一级,属于不同的包,类似 “文件夹和子文件夹的关系”。
  • 注意命名规范:Java 包名通常采用域名倒写 + 项目名(如 com.example),且严格区分大小写(com.User 和 com.user 也是不同包)。

什么是包访问权限?

  • 当类的成员(字段、方法)不添加任何访问修饰符时,默认拥有包访问权限(也叫默认权限或 friendly 权限)。
  • 拥有包访问权限的成员,只能被同一个包内的其他类访问,包外的类无法访问(相当于对包外是 “私有的”)。

包访问权限的作用

  • 封装的层次感:在public和private之间提供中间选项;
  • 模块的内聚性:强制相关类组织在同包,提升代码可维护性;
  • 接口的稳定性:保护内部实现,避免外部依赖细节。

继承与包访问权限

  • 子类继承父类时,若父类成员是包访问权限,子类必须与父类在同一个包内才能访问该成员(不同包的子类无法访问)

替代方案:get/set 方法:

  • 若需要在包外访问成员,但又不想设置为public,可以通过提供getter/setter方法(公开方法)来间接访问,同时保持成员的包访问权限。

Java 中 4 种访问权限修饰符的可见性规则如下

修饰符

类内

同包

子类(不同包)

其他包

private

包访问权限(默认,无修饰符)

protected

public

跨包继承的可行性

可以跨包继承,即子类可以和父类位于不同包中,但子类对父类成员的访问权限会受限制,具体取决于父类成员的访问修饰符:

父类成员修饰符

同包子类访问

跨包子类访问

public

可以

可以

protected

可以

可以

包访问权限(默认,无修饰符)

可以

不可以

private

不可以

不可以

注意:import并没有打破访问权限。import只是让代码可以用类名直接访问跨包的类,但能否调用类中的方法(包括构造方法),完全由方法的访问修饰符决定。如果一个类的构造方法是public的,通过import到另一个包的时候,可以通过 new 构造方法 创建对象。因为构造方法是public的,可以挎包使用,但是如果构造方法是private或者是默认的包内使用,就不能new 构造方法 来创建了。 另外private 构造方法 其实是实现单例的一个重要方法。

什么是 “默认包”?

当 Java 文件中没有写package语句时,该类属于 “默认包”。此时:

  • 类所在的当前目录就是默认包的作用范围
  • 同一目录下的所有未声明包的类,都属于同一个默认包,彼此之间可以直接访问包访问权限的成员。

注意:默认包在开发中几乎遇不到,默认包就像 “代码的临时垃圾桶”,只在极简单的场景下临时使用,正规开发中几乎见不到。它的存在主要是为了方便初学者入门,但从工程化角度看,违背了 Java 的包管理设计初衷,因此被开发者广泛 “抛弃”。

private的本质:“类内专属,外人免进”

  • private修饰的成员(构造方法、属性、方法)仅当前类可见,其他类(包括同包的类)都无法访问。
  • 类比:就像 “私人卧室”,只有自己能进,同住在一个房子(包)里的其他人也进不去。

二、private的关键作用

  1. 控制对象创建方式
代码语言:txt
复制
class Sundae {
    private Sundae() {} // 私有的构造方法,禁止外部直接new
    static Sundae makeASundae() {
        return new Sundae(); // 类内部创建实例并返回
    }
}

在外部不能通过new Sundae来创建实例对象,只能通过开放的接口makeASundae来创建实例对象,而makeASundae是可以自己来指定逻辑的。相当于控制了对象的创建方式

保护类的内部实现

  • 类中的 “辅助方法”(仅本类使用的工具方法)应声明为private,防止被包内其他类误用或修改。
  • 例如:一个计算逻辑的辅助方法private void calculate(),若设为public,可能被其他类错误调用,而private能确保它只在本类内使用。

隐藏属性,强制封装

  • 类的属性通常声明为private,通过publicgetter/setter方法暴露访问接口,符合面向对象的封装原则(如private int age; public int getAge() { return age; })。 封装原则的本质是将数据与操作数据的方法绑定,并隐藏内部实现细节,仅通过可控接口对外暴露功能

三、protected和继承访问权限

什么是继承?
  • 就像 “儿子继承父亲的财产”,Java 中一个类(子类)可以继承另一个类(父类)的属性和方法。比如: class 儿子 extends 父亲 {},儿子能直接用父亲的东西,还能自己添加新东西。
protected 的作用:给 “自家人” 开后门
  • 场景:父类想让子类能用某个方法,但不想让 “外人”(其他无关类)随便用。
  • 类比:家里的存折密码,只告诉子女(子类),不告诉外人(其他包的类),但同家族的亲戚(同包的类)也能知道。
  • 本质protected修饰的成员,子类(跨包也能访问)和同包的类可以用,但其他包的非子类不能用

注意:允许子类(无论是否跨包)在自身代码中调用父类的protected方法,但禁止非子类通过子类实例访问该方法。

对于上面的注意点,很多人可能会有误区,在这里用代码解释一下。

代码语言:javascript
复制
package A;

public class Parent {
    protected void fun(){
        System.out.println("父类函数打印test\n");
    }
}

代码语言:javascript
复制
package B;

import A.Parent;

public class Child extends Parent {
    public void funChild(){
        fun();
    }

    public void funB(){
        System.out.println("子类自己的打印方法\n");
    }
}

代码语言:javascript
复制
package C;

import A.Parent;
import B.Child;
public class OutClass {


    public void fun(){
        Child child=new Child();
        child.funChild();
        child.funB();
        child.fun()//这个是不可以的 会报错
    }

}

外类OutClass通过子类实例child,调用父类方法fun();是不可以的。child.fun()(错误的)。但是调用 child.funChild();是可以的,这里关键的一点是,OutClass并没有直接调用Child实例的fun()方法,而是调用了funChild()方法,而funChild()Child类自身的公共方法。

四、包的访问权限VSpublic构造器

核心逻辑:类的访问权限优先于构造器

类的访问权限是 “包访问权限”(默认修饰符)

  • 当类没有用public修饰时,它只能在当前包内被访问(即 “包访问权限”)。
  • 此时,类的所有构造器(包括public构造器)都会被类的访问权限 “覆盖”

构造器的public修饰符在包外无效

  • 例如:类A是包访问权限,即使它有public A()构造器,包外代码也无法通过该构造器创建对象,因为类本身不能被包外访问。
  • 就像 “房子的大门(类)没开,即使卧室门(构造器)是敞开的,外人也进不去”。

联系:这个和前面说的默认包不同,默认包是看有没有package不是看public。没有package即使有public也不能跨包访问。因为public 类的访问权限是 “所有包可见”,但默认包的特殊性导致其他包无法引用,因此实际效果与包访问权限类相同(只能在默认包内访问)。

五、类的访问权限

类的访问权限用于控制类库中哪些类可被外部使用。若希望类能被客户端使用,需用public修饰类,这也决定了客户端能否创建该类的对象。

注意:

  • 每个文件只能有一个public
  • public类名必须与文件名一致
  • 文件中可没有public
  • 类不能使用privateprotected修饰:类的访问权限只能是包访问权限或public,但可通过将构造器声明为private来间接限制类的使用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、包访问权限
    • 判断是否为同一个包的核心规则
    • 继承与包访问权限
    • Java 中 4 种访问权限修饰符的可见性规则如下
    • 跨包继承的可行性
    • 什么是 “默认包”?
    • private的本质:“类内专属,外人免进”
    • 二、private的关键作用
    • 三、protected和继承访问权限
    • 四、包的访问权限VSpublic构造器
    • 五、类的访问权限
    • 注意:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档