在 Java 里,Field(字段)本身是不能被“监听”的,因为字段只是内存中的变量,没有事件机制。
所谓“监听字段变化”,本质上都是在访问/修改字段的入口做文章。下面按常见方案从简单到高级说明。
这是 Java 中最标准、最清晰的方式。
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("name changed: " + this.name + " -> " + name);
this.name = name;
}
}
✅ 优点
❌ 缺点
user.name = "x")适合需要多个监听器的场景。
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class User {
private final PropertyChangeSupport support =
new PropertyChangeSupport(this);
private String name;
public void addListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
public void setName(String name) {
String old = this.name;
this.name = name;
support.firePropertyChange("name", old, name);
}
}
监听:
user.addListener(e ->
System.out.println(e.getPropertyName() + " changed"));
✅ 优点
适合不能改源码或统一拦截。
interface User {
void setName(String name);
String getName();
}
User proxy = (User) Proxy.newProxyInstance(
...,
new InvocationHandler() {
private String name;
public Object invoke(Object proxy, Method m, Object[] args) {
if ("setName".equals(m.getName())) {
System.out.println("set name");
}
return null;
}
});
适合框架级监听(如 Spring AOP)。
在 方法级别监听字段变化。
@Aspect
@Component
public class FieldWatchAspect {
@After("execution(* com.xxx.User.setName(..))")
public void watch() {
System.out.println("name changed");
}
}
✅ 优点
✅ 适合:
❌ 不适合普通业务
❌ 以下方式无法监听:
user.name = "xxx"; // 直接字段访问
除非:
volatile + 轮询(不推荐)| 场景 | 推荐方案 |
|---|---|
| 普通业务 | Setter 监听 |
| Java Bean | PropertyChangeSupport |
| Spring 项目 | AOP |
| 框架 / 监控 | 字节码增强 |
| 不改源码 | 动态代理 |
如果你能说一下:
我可以给你更具体的示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。