protected是为继承设计的受控可见性工具,允许在本类、同包任意类、不同包子类(通过this/super)中访问,禁止跨包非子类及父类引用访问,不可替代getter封装。

protected 不是用来“开放访问”的,而是为继承设计的受控可见性工具。它不解决“谁能拿到数据”,而是明确“谁能在哪用继承来的成员”。用对了,能自然支持子类复用;用错了,编译就报错,还容易破坏封装。
protected 的合法使用场景
它只在三类地方能直接写、不报错:
- 在定义它的那个类内部(本类中直接用)
- 在同一个包里的任意其他类中(不管是不是子类,都能访问)
- 在不同包的子类内部——但必须通过 this 或 super,也就是调用自己继承来的成员,而不是拿一个父类引用去点
跨包子类怎么安全用 protected 成员
子类在不同包里时,不能写 Parent p = new Child(); p.protectedField; —— 这会编译失败。正确方式只有这些:
- 在子类的实例方法里直接写
protectedField = 100;或this.protectedField - 用
super.protectedMethod()显式调用父类版本,语义清晰 - 在子类构造器或实例初始化块中访问继承来的 protected 成员
注意:哪怕对象实际是子类实例,只要引用类型是父类且跨包,就不允许访问。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
别把 protected 当成 getter 用
直接暴露 protected String data; 风险很大——子类可以随意改,父类无法控制。更稳妥的做法是:
- 字段设为
private,提供protected final String getData()方法,子类可读不可写 - 需要子类参与处理逻辑时,用
protected abstract void onReady(String data),由父类决定何时、传什么 - 返回不可变视图,比如
protected List<string> getItems() { return Collections.unmodifiableList(items); }</string>
常见错误与规避
以下写法在跨包子类中都会编译失败:
-
new Parent().protectedField—— 不是自己的继承链 -
Parent p = new Child(); p.protectedMethod()—— 引用类型是 Parent,跨包不认 - 在子类的
static方法里写new Child().protectedField—— 静态上下文不构成“实例继承访问”
如果发现总在绕过编译限制,说明设计可能偏了:该用接口抽象的,别硬靠修饰符撑;该封装逻辑的,别裸露字段。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










