11

在我的项目中,我有一个小型数据结构Key

public class Key implements Serializable {

  private static final long serialVersionUID = 1L;

  public String db;
  public String ref;
  public Object id;

  protected Key() {
  }

  public Key(String db, String ref, Object id) {
    this.db = db;
    this.ref = ref;
    this.id = id;
  }
}

是的,这个类很简单,每个字段都可以公开访问。

但是有人建议我改用POJO样式类,但是当我问他们为什么不能告诉我时。

在我看来,调用gettersetter比直接访问字段要慢。

那么为什么我必须使用POJO编程风格呢?

4

5 回答 5

20

取自维基百科:

POJO 是 Plain Old Java Object 的首字母缩写词。该名称用于强调给定对象是普通的 Java 对象,而不是特殊对象。

POJO 通常很简单,因此不依赖于其他库、接口或注释。这增加了可以在多种项目类型(Web、桌面、控制台等)中重用的机会。

正如有人已经在评论中指出的那样,您的对象在技术上已经是一个 POJO,但是您特别询问了更类似于 JavaBeans 的 getter 和 setter。

我可以想到使用 getter 和 setter 的原因有很多:

  1. 您可能只想获取一些值(IE 只读值)。使用字段,客户端可以直接获取和设置值。如果字段被标记为 final,则可以将它们设为只读,尽管这并不总是保证它们是不可变的(参见第 9 点)。
  2. Getter 和 setter 方法允许您在不破坏类的公共接口的情况下更改底层数据类型,这使得它(和您的应用程序)更加健壮和适应变化。
  3. 您可能希望调用其他代码,例如在获取或更改值时发出通知。这在您当前的课程中是不可能的。
  4. 您正在公开您的类的实现,这在某些情况下可能存在安全风险。
  5. Java bean 是围绕 POJO 设计的,这意味着如果您的类没有作为一个类来实现,那么某些希望您的类遵守这些完善的原则的工具和库就不能使用它。
  6. 您可以公开不受字段 IE 计算值支持的值,例如getFullName()哪些是字段的串联,getFirstName()哪些getLastName()由字段支持。
  7. 您可以向您的 setter 方法添加验证,以确保传递的值是正确的。这可确保您的类始终处于有效状态。
  8. 您可以在 getter 和 setter 中设置断点,以便在获取或更改值时调试代码。
  9. 如果该字段是一个对象(IE 不是原始类型),那么您的类的内部状态可以被其他对象修改,这可能会导致错误或安全风险。您可以通过返回对象的副本来防止 POJO 的 getter 中出现这种情况,以便客户端可以在不影响对象状态的情况下使用数据。请注意,拥有最终字段并不总是可以保护您免受此类攻击,因为客户端仍然可以更改被引用的对象(假设该对象本身是可变的),您只是不能将字段指向不同的引用,一旦它被设置.

是的,通过方法调用访问或设置值可能比直接访问字段要慢,但差异几乎不明显,它肯定不会成为程序的瓶颈。

虽然优点很明显,但这并不意味着 getter 和 setter 是灵丹妙药。在设计真实世界的、健壮的可扩展类时,需要考虑许多“陷阱”。

在设计具有 getter 和 setter 的类时,这个对非常相似的问题的回答详细研究了一些注意事项。尽管这些建议可能更相关,具体取决于您正在设计的类的类型,例如,在大型系统中构成 API 一部分的类,而不是简单的数据传输对象。

另请注意,在某些情况下,具有直接字段的类可能是有利的,例如当速度至关重要或内存有限时,尽管只有在分析您的代码并发现它实际上是一个瓶颈之后才应考虑这一点

还要注意,您不仅仅将所有字段包装在 getter 和 setter 中,因为这确实缺少封装的意义。

这个答案很好地总结了选择 POJO 而不是带有 getter 和 setter 的 JavaBean 样式对象的原因。

于 2013-01-05T14:29:46.310 回答
5

Use private class variables and public getters and setters which will provide you Encapsulation.

于 2013-01-05T14:21:12.517 回答
3

Getters and setters, especially the simplest forms will just be inlined by the JIT compiler and thus remove the method call overhead. This sounds very much like premature optimisation. If you ever get a bottleneck, then profile and look where it occurs. I am fairly certain it'll be not in property accesses.

于 2013-01-05T14:21:34.543 回答
3

给自己买一本《Effective Java》。

  • 第 14 项,在公共类中使用访问器方法而不是公共字段。

在这篇文章中,Joshua Bloch 说包私有或嵌套类中的公共字段没有固有的错误,但强烈建议不要使用公共类。

他对这个主题进行了更详细的介绍,这是一本很棒的书,建议你买一本。

于 2013-01-05T17:50:55.313 回答
1

想象一下,如果其他程序员正在使用您的代码。如果您不提供 setter 和 getter 方法,那么他可以直接调用您的变量,它肯定会影响您的代码。而且它可能会导致安全问题所以通过提供 POJO 类,你强迫他调用你的方法,而不是直接调用你的实例变量。

于 2015-03-02T06:20:08.220 回答