JavaBeans的替代品?

Sam*_*ran 11 java properties javabeans

我讨厌JavaBeans模式的激情像一千个太阳的火焰一样燃烧.为什么?

  • 详细.这是2009年.我不应该为房产写7 LOC.如果他们有事件听众,那么请抓住你的帽子.
  • 没有类型安全的参考.没有类型安全的方法来引用属性.Java的全部意义在于它是类型安全的,并且它最流行的模式并不是所有类型都安全的.

我想要的是:

class Customer {
    public Property<String> name = new Property();
}
Run Code Online (Sandbox Code Playgroud)

我主要是一名Web开发人员,因此需要JPA和Wicket支持.

帮助我离开javabean火车!

Dav*_*Ray 10

我认为你与那里的宣言非常接近(见下面的草图).但是,通过使用非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(); }
}
Run Code Online (Sandbox Code Playgroud)

然后继续使用它:

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);
Run Code Online (Sandbox Code Playgroud)

因此,现在声明属性是一行代码,并包含属性更改支持.我调用了方法setValue()和getValue(),所以它仍然看起来像一个bean来代码像Rhino和东西,但为了简洁,你可以添加get()和set().其余部分留给读者练习:

  • 正确处理序列化
  • 处理空值检查
  • 如果您关心自动装箱开销,可能会为原子类型添加一个专门化.
  • ?? 我相信还有更多陷阱

另请注意,您可以子类化(通常作为匿名类)并覆盖setValue()以提供其他参数检查.

我不认为你真的可以摆脱"字符串引用",因为这几乎就是反射的全部内容.

可悲的是,在这个时代,这仍然有点像汇编编程......如果你有选择的话,Groovy,C#等等可能仍然是更好的选择.


Sco*_*eld 5

查看我的 Bean 注释:

http://code.google.com/p/javadude/wiki/Annotations

基本上你会做这样的事情:

@Bean(
  properties={
    @Property(name="name"),
    @Property(name="phone", bound=true),
    @Property(name="friend", type=Person.class, kind=PropertyKind.LIST)
  }
)
public class Person extends PersonGen {}
Run Code Online (Sandbox Code Playgroud)

而不是自己定义所有这些额外的 get/set 等方法。

还有其他属性可以定义 equals/hashCode、观察者、委托、mixins 等。

它是一组注释和注释处理器,在 eclipse 或命令行构建中运行(例如在 ant 中)。处理器生成一个超类来包含所有生成的代码(注释处理器无法更改包含注释的类,顺便说一句)