欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

到底什么是POJO?

程序员文章站 2022-05-19 13:13:37
...

概述

POJO即“Plain Old Java Object”,下面我们将POJO与JavaBean进行比较,以及如何将POJO转换为JavaBeans。

Plain Old Java Object

什么是POJO?

一般当我们谈论POJO时,描述的是一种简单的类型,没有涉及到任何框架。POJO对属性和方法没有命名约定。

当我们创建一个员工POJO,它具有三个属性:fisrtName、lastName、startDate。

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;
    }
}

EmployeePojo可以被任何Java程序使用,因为它没有框架的束缚。但是,我们并没有遵循任何真正的约定来构造、访问、或者修改字段的值。缺乏约定会导致两个问题:

  1. 使用它的人会增加学习难度。
  2. 它可能会限制框架支持约定而不是配置,了解如果使用它以及扩展。

 

为了探究第二点,我们使用反射来获取EmployeePojo的属性。这样,我们将发现它的一些局限性。

对POJO进行反射

添加BeanUtils的Maven依赖到项目中:

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

接下来,让我们使用反射获取POJO的属性:

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

执行代码,我们将看到:

[start]

是不是很懵逼?我们只看到了start (getStart),PropertyUtils找不到其他两个属性,甚至是真实的属性。

如果你使用Jackson一样的其他库来处理,同样也会遇到这个问题。理想情况下,我们将看到的结果是:firstName,lastName,startDate。好的消息是,许多的Java库默认支持JavaBean的命名约定。

JavaBeans

什么是JavaBean?

JavaBean仍然是POJO,但是它遵守一组严格的规则:

  1. 访问级别 - JavaBean的属性必须是私有的,get、set方法是public
  2. 方法名称 - getter和setter遵循getX和setX的约定(对于Boolean,isX替代getter)
  3. 默认构造函数 - 必须存在无参的构造函数,一遍可以在不提供参数的情况下创建实例,例如:序列化期间
  4. 可序列化 - 实现Serializable接口,允许存储状态

EmployeePojo转换为JavaBean

我们尝试将EmplyeePojo转换为JavaBean:

public class EmployeeBean implements Serializable {
private static final long serialVersionUID = 5570916775939868315L;
private String firstName;
private String lastName;
private LocalDate startDate;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
}

 对JavaBean进行反射

当我们对JavaBean进行时,获得了属性的完整列表:

[firstName, lastName, startDate]

是否使用JavaBeans

这里展示了JavaBeans的一种用法。每个设计都需要权衡,当我们使用JavaBeans时,还应该注意一些潜在的问题:

  1. 可变性 - 我们的JavaBeans由于使用setter方法,随时可以修改。这可能导致一些并发问题或者一致性问题
  2. 灵活性 - 一般我们必须为所有的属性设置一个值,其中大部分可能都是没有必要的。例如使用JPA修改密码时,我可能只需要userId和password
  3. 无参构造函数 - 我们经常通过有参构造函数来确保对象以有效的状态实例化,但是JavaBean标准要求我们提供了无参构造函数

结论

我们将POJO与JavaBeans进行了比较,POJO是一个没有任何约束且没有特定框架绑定的Java对象,而JavaBean时具有严格约定的POJO的一种特殊类型。

相关标签: Java java