桥接方法的访问修饰符继承自真实重写方法,后者必须至少与父类方法一样公开(如父类public则子类必须public),否则编译失败,根本不会生成桥接方法。

隐式桥接方法的访问修饰符本身不会造成可见性瓶颈,真正卡住的是你写的那个真实重写方法的修饰符——它必须至少和父类方法一样公开,否则编译器连生成桥接方法的机会都没有。
桥接方法不决定可见性,真实方法才决定
桥接方法是编译器自动生成的合成方法(ACC_BRIDGE | ACC_SYNTHETIC),它的访问修饰符完全继承自你手写的重写方法。也就是说:
- 如果你在子类里把重写方法写成 private 或 package-private(不加 public),而父类方法是 public,那根本通不过编译,报错“试图降低继承方法的可见性”
- 只有当你写的重写方法是 public(或 protected,但需满足父类可见性范围),编译器才会生成桥接方法,并让它也是 public
- 桥接方法自己不能被显式声明,也不能加 @Override,更不能改修饰符——它只是个字节码层面的转发壳
跨包继承时最常踩的坑:父类方法是 public,子类重写却漏写 public
尤其在跨包场景下,开发者容易忽略 Java 的可见性规则:子类重写父类 public 方法时,重写方法也必须是 public。常见错误写法:
-
错误:父类在 com.example.base 里定义
public <T> T get(int),子类在 com.example.impl 里只写<T> T get(int)(缺 public)→ 编译失败 - 错误:父类方法是 protected,子类跨包重写却用 public → 允许,但语义越权;若用 package-private → 编译失败
-
正确:子类方法签名完全匹配(含泛型形参、返回类型协变),且显式加上
public
排查步骤:从源码到字节码逐层验证
当遇到“明明写了重写方法却调用不到”,按顺序检查:
- 查源码:确认子类方法是否带
public(跨包必须),是否与父类方法名、参数列表(含泛型形参)、返回类型协变关系一致 - 查编译结果:用
javap -v YourSubclass.class,搜索ACC_BRIDGE标志 —— 如果没看到,说明编译压根没通过,问题出在源码可见性或签名匹配上 - 查运行时行为:如果桥接方法存在但调用仍异常,可能是调用方用了反射或 AOP,误绑到了桥接方法而非真实方法(此时桥接方法虽 public,但无业务注解、无逻辑)
工具辅助:快速识别真实方法与桥接方法的关系
在调试或 AOP 场景中,别只看 joinPoint.getSignature().getMethod() 返回的对象。应主动判断:
- 调用
method.isBridge()→ 若为 true,立刻用BridgeMethodResolver.findBridgedMethod(method)拿到原始方法 - 再检查原始方法的
getModifiers(),确认它是 public;同时检查其getDeclaringClass().getPackage()是否与调用方同包或可访问 - 打印两者的
toGenericString()对比,能直观看出桥接方法如何做类型擦除适配(如String get(int)→Object get(int))

















