1. 概要

この短いチュートリアルでは、「PlainOldJavaObject」または略してPOJOの定義を調査します。

POJOをJavaBeanと比較する方法と、POJOをJavaBeanに変換することがどのように役立つかを見ていきます。

2. プレーンオールドJavaオブジェクト

2.1. POJO とは何ですか?

POJOについて話すとき、私たちが説明しているのは、特定のフレームワークへの参照がない単純なタイプです。 POJOには、プロパティとメソッドの命名規則はありません。

基本的な従業員POJOを作成しましょう。 3つのプロパティがあります。 名、姓、および開始日:

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

このクラスは、フレームワークに関連付けられていないため、どのJavaプログラムでも使用できます。

ただし、クラスの状態を構築、アクセス、または変更するための実際の規則に従っていません。

この慣習の欠如は2つの問題を引き起こします:

まず、使用方法を理解しようとするコーダーの学習曲線が長くなります。

第二に、設定より規約を優先し、クラスの使用方法を理解し、その機能を強化するフレームワークの機能を制限する可能性があります。

この2番目のポイントを調べるために、リフレクションを使用してEmployeePojoを操作してみましょう。 したがって、その制限のいくつかを見つけ始めます。

2.2. POJOによるリフレクション

commons-beanutils依存関係をプロジェクトに追加しましょう。

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

それでは、POJOのプロパティを調べてみましょう。

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

propertyNames をコンソールに出力すると、次のように表示されます。

[start]

ここでは、クラスのプロパティとしてstartのみを取得していることがわかります。 PropertyUtilsは他の2つを見つけることができませんでした。

Jacksonなどの他のライブラリを使用してEmployeePojo。を処理した場合も、同じような結果が得られます。

理想的には、すべてのプロパティが表示されます。 ファーストネーム 苗字、開始日。 そして幸いなことに、多くのJavaライブラリは、デフォルトでJavaBean命名規則と呼ばれるものをサポートしています。

3. JavaBeans

3.1. JavaBean とは何ですか?

JavaBeanは依然としてPOJOですが、実装方法に関する一連の厳密なルールが導入されています。

  • アクセスレベル–私たちのプロパティはプライベートであり、ゲッターとセッターを公開しています
  • メソッド名–ゲッターとセッターはgetXsetXの規則に従います(ブール値の場合、 isX をゲッターに使用できます)
  • デフォルトコンストラクター–引数を指定せずにインスタンスを作成できるように、たとえば逆シリアル化中に、引数なしのコンストラクターが存在する必要があります
  • シリアル化可能– Serializable インターフェースを実装すると、状態を保存できます

3.2.  EmployeePojoJavaBeanとして

それでは、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. JavaBeanによるリフレクション

Beanをリフレクションで検査すると、プロパティの完全なリストが表示されます。

[firstName, lastName, startDate]

4. JavaBeansを使用する場合のトレードオフ

そこで、JavaBeansが役立つ方法を示しました。 すべての設計の選択にはトレードオフが伴うことに注意してください。

JavaBeansを使用するときは、いくつかの潜在的な欠点にも注意する必要があります。

  • ミューテイタビリティ– JavaBeansは、セッターメソッドのためにミューテイタブルです–これにより、同時実行性または一貫性の問題が発生する可能性があります
  • ボイラープレート–すべてのプロパティにゲッターを導入する必要があり、ほとんどの場合セッターを導入する必要があります。これの多くは不要な場合があります
  • ゼロ引数コンストラクター–オブジェクトが有効な状態でインスタンス化されるようにするために、コンストラクターに引数が必要になることがよくありますが、JavaBean標準では、引数なしのコンストラクターを提供する必要があります。

これらのトレードオフを考えると、フレームワークは何年にもわたって他のBeanの規則にも適応してきました。

5. 結論

このチュートリアルでは、POJOとJavaBeansを比較しました。

最初に、POJOは特定のフレームワークにバインドされていないJavaオブジェクトであり、JavaBeanは厳密な規則のセットを持つ特殊なタイプのPOJOであることを学びました。

次に、一部のフレームワークとライブラリがJavaBeanの命名規則を利用して、クラスのプロパティを検出する方法を確認しました。

いつものように、例はGitHubから入手できます。