Java跨包继承报“Cannot resolve symbol”错误,根本原因是无名包类不可被其他包访问;须为所有类显式声明包名、严格匹配目录结构,并在子类中import父类全限定名。

Java 中跨包调用引发的编译错误,绝大多数不是访问修饰符本身写错了,而是**修饰符与包结构、导入声明、模块配置不匹配**导致编译器“看不见”目标成员。排查重点不在改修饰符,而在理清“谁在哪儿、谁能看谁”。
确认报错类型是编译期错误而非运行时异常
先区分清楚:如果报错是 cannot resolve symbol 或 is not public in,属于编译失败;如果是 IllegalAccessError,则是运行时报错(说明编译通过了,但 JVM 拒绝执行)。本文聚焦前者——即代码根本编译不过。
- cannot resolve symbol Xxx:编译器连类名/方法名都找不到,大概率缺 import、包路径错、或类根本没声明 package
- Xxx is not public in Yyy; cannot be accessed from outside package:明确提示访问级别不足,说明编译器找到了类,但发现你要访问的成员(字段/方法)是 package-private(默认),而你不在同一个包里
检查父类成员的修饰符与子类所在包是否匹配
Java 规定:package-private 成员(无任何修饰符)只能被**同一运行时包**下的类访问。注意,“同一包名”不等于“可跨包继承”。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 若父类中字段或方法是 public 或 protected,子类跨包继承后可直接使用(前提是已 import 父类)
- 若父类成员是 默认访问级别(无修饰符),子类即使 extends 了父类,也无法访问该成员——编译直接报错,且错误信息会明确指出“not public in...”
- 不要依赖 IDE 自动 import 同名类:比如两个不同 JAR 里都有
com.example.Utils,但一个在 unnamed module,一个在 named module,import 可能导错,导致实际访问的是不可见版本
验证 import 和 package 声明是否真实一致
Java 编译器不看文件夹路径,只认源码顶部的 package 声明和 import 语句。三者必须闭环:
立即学习“Java免费学习笔记(深入)”;
- 父类文件开头有
package com.example.base;→ 它就必须放在src/main/java/com/example/base/目录下 - 子类要继承它,必须写
import com.example.base.ParentClass;(不能只靠同目录自动可见) - 子类自己的
package必须显式声明(如package com.example.test;),绝不能留空(即掉进 unnamed package)——因为 unnamed package 无法 import 任何其他包,也无法被其他包 import
模块化项目需额外检查 exports/opens
Java 9+ 使用模块系统(JPMS)后,即使修饰符是 public,包也必须显式导出才能被其他模块访问。
- 查看父类所在模块的
module-info.java,确认是否包含类似exports com.example.base; - 如果子类要用反射访问父类字段(如框架序列化),还需
opens com.example.base; - 若依赖的是未模块化的老 JAR(automatic module),它默认无法访问你的导出包,此时要么升级该依赖,要么用
--add-opens启动参数临时放开(仅调试)

















