You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring CGLIB代理final方法内访问实例变量为null的原因咨询

问题解答

你的理解完全准确,这个现象是CGLIB代理实现机制和final方法语义共同作用的结果,和业务代码里的字段初始化逻辑无关。

对应你给出的示例代码:

class A {
  String prop = "a";

  public final String eat(){
    return prop;
  }
}

出现null返回值的完整逻辑链如下:

  • CGLIB代理的核心实现是动态生成目标类的子类,对非final的父类方法进行重写,插入AOP增强逻辑,方法调用时会先执行代理逻辑,再转发到真实初始化完成的目标实例执行原方法。
  • final修饰的方法不允许子类重写,因此代理子类不会对eat()方法做重写和转发逻辑,当你调用代理实例的eat()方法时,实际执行的是代理子类自身继承自父类的eat()方法,根本不会触达已经完成字段初始化的真实目标实例。
  • Spring生成CGLIB代理实例时,确实是通过SpringObjenesis#newInstance完成对象创建,该方式会绕过类的构造函数、实例字段初始化赋值、实例初始化块的所有逻辑,创建出的对象所有字段都保持JVM默认初始值:引用类型为null,数值类型为0,布尔类型为false。你在final方法中访问的prop字段,本质是代理子类实例自身未被赋值的字段,因此返回null。

补充说明:这也是Spring AOP场景下不建议给需要被代理的Bean的方法加final修饰的核心原因,不止字段取值问题,final方法内的所有逻辑都不会被AOP增强,还可能出现各类实例状态未初始化的异常。

内容的提问来源于stack exchange,提问作者silver-soul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:09:23