java中object类本身不提供变更通知能力,需通过javabeans规范配合propertychangelistener、动态代理、observableobject基类或propertydescriptor内省等机制实现属性变化通知。

Java 中 Object 类本身不提供变更通知能力,它不能直接配合事件监听器实现对象属性变化的自动通知。要实现通用对象变更通知,必须借助额外机制——比如手动触发事件、使用代理(如 CGLIB 或 JDK 动态代理)、或基于 JavaBeans 规范封装可观察行为。核心思路是:把“对象变更”这个语义从底层 Object 抽离出来,由上层约定和工具来承载。
用 JavaBeans + PropertyChangeListener 实现基础通知
这是最贴近标准、无需第三方库的方式。要求目标类遵循 JavaBeans 规范(提供 getter/setter),并继承 PropertyChangeSupport 或组合其实例:
- 在类中声明
private PropertyChangeSupport pcs = new PropertyChangeSupport(this); - 每个 setter 方法末尾调用
pcs.firePropertyChange("propertyName", oldValue, newValue); - 监听方通过
addPropertyChangeListener("name", listener)注册回调 -
Object类在此仅作为基类存在,实际通知逻辑完全由业务类自己控制
用动态代理拦截 set 操作实现透明通知
若不想修改每个实体类代码,可用 JDK 动态代理或 CGLIB 对 setter 方法做统一拦截:
- JDK 代理要求目标类实现接口;CGLIB 可代理具体类(需无 final 方法)
- 代理逻辑中识别 setter 调用,提取属性名与新旧值,再触发统一的事件分发器
- 例如:拦截
setName(String),反射获取原值,调用后再次获取,对比后发布PropertyChangeEvent - 此时
Object是代理目标的父类,但通知能力来自代理逻辑,而非Object自身
用 ObservableObject 封装通用可观察行为
可以定义一个泛型基类(如 ObservableObject<t></t>),内部持有 PropertyChangeSupport,并通过泛型方法支持属性更新与通知:
- 提供
setAndNotify(String prop, T oldValue, T newValue)统一入口 - 子类只需在 setter 中调用该方法,避免重复写
firePropertyChange - 仍需继承或组合该基类——
Object仍是隐式父类,但可观察性由显式设计注入 - 比直接操作
PropertyChangeSupport更简洁,适合中等规模模型层
现代替代方案:用 PropertyDescriptor + Introspector 自动绑定
对已有 POJO(未侵入式改造的普通 JavaBean),可通过反射+内省机制实现运行时监听:
- 用
Introspector.getBeanInfo(clazz)获取所有PropertyDescriptor - 为每个可写的属性生成带通知逻辑的 setter 代理方法
- 配合 WeakReference 避免监听器内存泄漏
- 这种方案完全绕过源码修改,但性能开销略高,适合配置类或低频变更场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











