What is a POJO Class? – 什么是POJO类?

最后修改: 2019年 11月 15日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we’ll investigate the definition of “Plain Old Java Object” or POJO for short.

在这个简短的教程中,我们将研究 “Plain Old Java Object”或简称为POJO的定义。

We’ll look at how a POJO compares to a JavaBean, and how turning our POJOs into JavaBeans can be helpful.

我们将看看POJO与JavaBean的比较,以及将我们的POJO变成JavaBean会有什么帮助。

2. Plain Old Java Objects

2.普通老式的Java对象

2.1. What Is a POJO?

2.1.什么是POJO

When we talk about a POJO, what we’re describing is a straightforward type with no references to any particular frameworks. A POJO has no naming convention for our properties and methods.

当我们谈论一个POJO时,我们所描述的是一个直接的类型,没有对任何特定框架的引用。一个POJO对于我们的属性和方法没有命名规则

Let’s create a basic employee POJO. It’ll have three properties; first name, last name, and start date:

让我们创建一个基本的雇员POJO。它将有三个属性:名、姓、和开始日期。

public class EmployeePojo {

    public String firstName;
    public String lastName;
    private LocalDate startDate;

    public EmployeePojo(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String name() {
        return this.firstName + " " + this.lastName;
    }

    public LocalDate getStart() {
        return this.startDate;
    }
}

This class can be used by any Java program as it’s not tied to any framework.

这个类可以被任何Java程序使用,因为它不与任何框架相联系。

But, we aren’t following any real convention for constructing, accessing, or modifying the class’s state.

但是,我们在构建、访问或修改类的状态时并没有遵循任何真正的惯例。

This lack of convention causes two problems:

这种缺乏惯例的做法造成了两个问题。

First, it increases the learning curve for coders trying to understand how to use it.

首先,它增加了试图了解如何使用它的编码员的学习曲线。

Second, it may limit a framework’s ability to favor convention over configuration, understand how to use the class, and augment its functionality.

其次,它可能会限制框架的能力,使其倾向于惯例而非配置,了解如何使用该类,并增强其功能。

To explore this second point, let’s work with EmployeePojo using reflection. Thus, we’ll start to find some of its limitations.

为了探索这第二点,让我们用EmployeePojo使用反射来工作。因此,我们将开始发现它的一些局限性。

2.2. Reflection with a POJO

2.2.用POJO进行反思

Let’s add the commons-beanutils dependency to our project:

让我们把commons-beanutils 依赖添加到我们的项目。

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

And now, let’s inspect the properties of our POJO:

现在,让我们检查一下我们的POJO的属性。

List<String> propertyNames =
  PropertyUtils.getPropertyDescriptors(EmployeePojo.class).stream()
    .map(PropertyDescriptor::getDisplayName)
    .collect(Collectors.toList());

If we were to print out propertyNames to the console, we’d only see:

如果我们要把属性名打印到控制台,我们只会看到。

[start]

Here, we see that we only get start as a property of the class. PropertyUtils failed to find the other two.

在这里,我们看到我们只得到start作为类的一个属性。PropertyUtils未能找到其他两个。

We’d see the same kind of outcome were we to use other libraries like Jackson to process EmployeePojo.

如果我们使用其他库,如Jackson来处理EmployeePojo.,我们会看到同样的结果。

Ideally, we’d see all our properties: firstName, lastName, and startDate. And the good news is that many Java libraries support by default something called the JavaBean naming convention.

理想情况下,我们会看到我们所有的属性。firstName, lastName, startDate。而好消息是,许多Java库默认支持一种叫做JavaBean的命名规则。

3. JavaBeans

3.JavaBeans

3.1. What Is a JavaBean?

3.1.什么是JavaBean

A JavaBean is still a POJO but introduces a strict set of rules around how we implement it:

JavaBean仍然是一个POJO,但围绕着我们如何实现它引入了一套严格的规则:

  • Access levels – our properties are private and we expose getters and setters
  • Method names – our getters and setters follow the getX and setX convention (in the case of a boolean, isX can be used for a getter)
  • Default Constructor – a no-argument constructor must be present so an instance can be created without providing arguments, for example during deserialization
  • Serializable – implementing the Serializable interface allows us to store the state

3.2. EmployeePojo as a JavaBean

3.2.EmployeePojo 作为一个JavaBean

So, let’s try converting EmployeePojo into a JavaBean:

所以,让我们试着将EmployeePojo转换为一个JavaBean。

public class EmployeeBean implements Serializable {

    private static final long serialVersionUID = -3760445487636086034L;
    private String firstName;
    private String lastName;
    private LocalDate startDate;

    public EmployeeBean() {
    }

    public EmployeeBean(String firstName, String lastName, LocalDate startDate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.startDate = startDate;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    //  additional getters/setters

}

3.3. Reflection with a JavaBean

3.3.用JavaBean进行反射

When we inspect our bean with reflection, now we get the full list of the properties:

当我们用反射检查我们的Bean时,现在我们得到了完整的属性列表。

[firstName, lastName, startDate]

4. Tradeoffs When Using JavaBeans

4.使用JavaBeans时的权衡

So, we’ve shown a way in which JavaBeans are helpful. Keep in mind that every design choice comes with tradeoffs.

所以,我们已经展示了一种JavaBeans的帮助方式。请记住,每一个设计选择都是有取舍的。

When we use JavaBeans we should also be mindful of some potential disadvantages:

当我们使用JavaBeans时,我们也应该注意到一些潜在的缺点:

  • Mutability – our JavaBeans are mutable due to their setter methods – this could lead to concurrency or consistency issues
  • Boilerplate – we must introduce getters for all properties and setters for most, much of this might be unnecessary
  • Zero-argument Constructor – we often need arguments in our constructors to ensure the object gets instantiated in a valid state, but the JavaBean standard requires us to provide a zero-argument constructor

Given these tradeoffs, frameworks have also adapted to other bean conventions over the years.

鉴于这些权衡,多年来框架也适应了其他Bean惯例。

5. Conclusion

5.总结

In this tutorial, we compared POJOs with JavaBeans.

在本教程中,我们比较了POJOs和JavaBeans。

First, we learned a POJO is a Java object that is bound to no specific framework, and that a JavaBean is a special type of POJO with a strict set of conventions.

首先,我们了解到POJO是一种不受特定框架约束的Java对象,而JavaBean是一种特殊的POJO类型,有一套严格的约定。

Then, we saw how some frameworks and libraries harness the JavaBean naming convention to discover a class’s properties.

然后,我们看到一些框架和库是如何利用JavaBean的命名规则来发现一个类的属性的。

As usual, the examples are available over on GitHub.

像往常一样,这些例子可以在GitHub上找到over