我认为您与那里的声明非常接近(请参见下面的草图)。但是,通过使用非 bean 方法,您可能会失去大多数假定 JavaBeans 协议有效的工具所提供的支持。请善待。下面的代码不在我的脑海中......
public class Property<T> {
public final String name;
T value;
private final PropertyChangeSupport support;
public static <T> Property<T> newInstance(String name, T value,
PropertyChangeSupport support) {
return new Property<T>(name, value, support);
}
public static <T> Property<T> newInstance(String name, T value) {
return newInstance(name, value, null);
}
public Property(String name, T value, PropertyChangeSupport support) {
this.name = name;
this.value = value;
this.support = support;
}
public T getValue() { return value; }
public void setValue(T value) {
T old = this.value;
this.value = value;
if(support != null)
support.firePropertyChange(name, old, this.value);
}
public String toString() { return value.toString(); }
}
然后继续使用它:
public class Customer {
private final PropertyChangeSupport support = new PropertyChangeSupport();
public final Property<String> name = Property.newInstance("name", "", support);
public final Property<Integer> age = Property.newInstance("age", 0, support);
... declare add/remove listenener ...
}
Customer c = new Customer();
c.name.setValue("Hyrum");
c.age.setValue(49);
System.out.println("%s : %s", c.name, c.age);
因此,现在声明一个属性是一行代码,并且包括属性更改支持。我调用了 setValue() 和 getValue() 方法,所以它看起来仍然像一个 bean 来编写 Rhino 之类的代码,但为了简洁起见,您可以只添加 get() 和 set()。其余的留给读者练习:
- 正确处理序列化
- 处理空值检查
- 如果您关心自动装箱开销,可能会为原子类型添加专业化。
- ?? 我敢肯定还有更多的陷阱
另请注意,您可以子类化(通常作为匿名类)并覆盖 setValue() 以提供额外的参数检查。
我认为您无法真正摆脱“字符串引用”,因为这几乎就是反射的全部内容。
可悲的是,在这个时代,这仍然有点像汇编编程......如果你有选择的话,Groovy、C# 等可能仍然是更好的选择。