JavaBean类规则

6

如何编写JavaBean类的正确规则是什么?

我有些困惑,因为一些书籍使用“必须”(MUST),而其他书籍使用“应该”(SHOULD)或“可以”(COULD)来描述编写规则:

例如:

  • 一个bean类必须实现Serializable接口,还是应该实现?
  • 实例变量必须是private,还是应该是private?
5个回答

7

JavaBean是由其属性(即getter和setter方法)定义的,而不是它的字段。尽管这些术语可以互换使用,但实际上并不正确。Introspector机制完全忽略字段。

例子

以这个(设计糟糕的)JavaBean为例:

public class TestBean {
    private int baz;
    private char[] phleem;

    public String getFoo() {
        return new String(phleem);
    }
    public void setFoo(final String foo) {
        this.phleem = foo.toCharArray();
    }
    public long getBar() {
        return baz;
    }
    public void setBar(final long bar) {
        this.baz = (int) bar;
    }
}

你可能会认为这些属性是:

  • "baz" (int)
  • "phleem" (char[])

但现在让我们使用JavaBeans内省器来检查它:

for (PropertyDescriptor descriptor : Introspector
        .getBeanInfo(TestBean.class, Object.class)
        .getPropertyDescriptors()) {
    System.out.println("Name: " + descriptor.getName() + 
                     ", type: " + descriptor.getPropertyType());
}

这是输出结果:
Name: bar, type: long
Name: foo, type: class java.lang.String

结论:

Getter和Setter是定义JavaBean属性的方式。它们通常与同名和类型的字段相关联,但实际上这些字段并不是JavaBean属性的一部分(尽管许多文档可能会建议这样做)。


在重新阅读我的答案时,我想补充一下其他答案。如果你想要一个简短而简单的答案,请选择skaffman的答案。


抱歉,我不太理解。如果变量名和get/set方法名之间没有强制匹配,构建工具如何根据变量名获取或设置该变量呢? - xdevel2000
1
@xdevel2000:因为这个“不匹配”是由JavaBean规范定义的,作为命名约定。 - skaffman
就像我说的:这只是一个约定,不要超过此范畴。在99%的情况下,您应该使用此约定,并且工具仅在使用此约定时才能帮助您。但是,我只想让您知道,底层字段不是 bean 属性,而 getter 和 setter 方法是。 - Sean Patrick Floyd
这并不是很相关(而且是一个旧回答),但是你为什么提到设计得很糟糕呢? - sdasdadas
@sdasdadas 这并不是那么可怕,只是有误导性。 - Sean Patrick Floyd

2
  • 这是一个公共类。

  • 它有一个公共的无参构造函数(虽然也可能有其他构造函数)。

  • 它实现了Serializable接口(即可以被持久化,因此它的状态可以被保存)。

  • 它具有使用JavaBeans命名模式命名的“getter”和“setter”方法的属性。

  • 它具有按照标准Java事件模型的事件,注册方法的命名方式遵循JavaBeans命名模式。

  • 它可能还具有其他不符合命名模式的方法。 这些方法不会被生成器工具暴露出来。


1

补充前面的帖子 - skaffman。重写toString()hashCode()equals()并编写一个重载构造函数,该构造函数将所有字段(此类具有的字段)作为输入。

请确保在toString()hashCode()的实现中不使用其他引用(如List、HashMap等)。

顺便说一句,Eclipse具有内置功能可为您生成它们。


1

Java Bean是一个Java类,应该遵循以下惯例:

  • 它应该有一个无参构造函数。
  • 它应该是Serializable的。
  • 它应该提供设置和获取属性值的方法,称为gettersetter方法。

0
所有上述内容都不应越过Java API的边界。这意味着它不应扩展或实现任何类或接口,但有一个例外,它可以仅实现一个可序列化接口,因为它是一个标记接口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接