允许将 protected 升为 public,因 java 规定重写方法访问权限只能相同或更宽松;此举维护多态安全、不破坏里氏替换原则,但需满足可继承、异常处理等条件。

合规,完全合法且常见。
为什么允许从 protected 升为 public
Java 明确规定:子类重写父类方法时,访问权限只能相同或更宽松,不能更严格。protected 属于中间层级,public 是最高可见性,因此升级符合语言规范。
- 这是编译器强制保障的规则,不是建议而是硬性要求
- 目的在维护多态安全——比如 Animal a = new Dog(); a.sound(); 调用必须始终成功,只要父类声明为 protected,子类升为 public 不会影响该调用,反而让 Dog d = new Dog(); d.sound(); 在包外也能直接使用
- 不会破坏里氏替换原则,只扩展了子类的可用范围
必须同时满足的配套条件
仅改修饰符不够,否则可能编译失败或运行异常:
- 父类方法本身必须可被继承(不能是 private)
- 若重写的是 Object.clone(),子类必须实现 Cloneable 接口
- 需正确处理原方法声明的检查型异常(如 CloneNotSupportedException)
- 推荐使用协变返回类型(例如返回具体子类而非 Object),提升类型安全性
典型正确写法示例
以重写 clone() 为例:
public class Person implements Cloneable {
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError("Unexpected", e);
}
}
}
这样外部代码就能直接写:Person p2 = p1.clone();
容易踩的坑
看似小改动,实则影响调用链:
- IDE 自动生成 @Override 方法时默认加 public,手动删成 protected 会导致编译报错:Cannot reduce the visibility
- 单元测试常与类同包运行,权限问题被掩盖;但 Spring 或框架反射跨包调用时会直接失败
- 误以为 “protected 更安全” 而主动降级,结果编译器立刻拦截——这不是风格选择,是语言铁律
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











