1. 概要

Apache Commons BeansUtilsには、JavaBeanの操作に必要なすべてのツールが含まれています。

簡単に言うと、Beanは、フィールド、ゲッター/セッター、および引数なしのコンストラクターを含む単純なJavaクラスです。

Javaは、ゲッターセッターメソッドを識別して動的に呼び出すためのリフレクションおよびイントロスペクション機能を提供します。 ただし、これらのAPIは習得が難しい場合があり、開発者が最も単純な操作を実行するためにボイラープレートコードを作成する必要がある場合があります。

2. Mavenの依存関係

Mavenの依存関係は、使用する前にPOMファイルに含める必要があります。

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

最新バージョンはここにあります。

3. JavaBeanの作成

典型的なgetterメソッドとsetterメソッドを使用して、2つのBeanクラスCourseStudentを作成しましょう。

public class Course {
    private String name;
    private List<String> codes;
    private Map<String, Student> enrolledStudent = new HashMap<>();

    //  standard getters/setters
}

public class Student {
    private String name;

    //  standard getters/setters
}

コースクラスには、コース名、コースコード、および複数の登録済みの学生が含まれています。 登録された学生は、一意の登録IDによって識別されます。 Course クラスは、登録済みの学生を Map オブジェクトに保持します。ここで、登録IDがキーであり、学生オブジェクトが値になります。

4. プロパティへのアクセス

Beanプロパティは、3つのカテゴリに分類できます。

4.1. シンプルなプロパティ

単一値のプロパティは、単純またはスカラーとも呼ばれます。

それらの値は、プリミティブ(int、floatなど)または複合型オブジェクトである可能性があります。 BeanUtilsにはPropertyUtilsクラスがあり、JavaBeanの単純なプロパティを変更できます。

プロパティを設定するためのサンプルコードは次のとおりです。

Course course = new Course();
String name = "Computer Science";
List<String> codes = Arrays.asList("CS", "CS01");

PropertyUtils.setSimpleProperty(course, "name", name);
PropertyUtils.setSimpleProperty(course, "codes", codes);

4.2. インデックス付きプロパティ

インデックス付きプロパティには、インデックス番号を使用して個別にアクセスできる値としてのコレクションがあります。 JavaBeanの拡張として、BeanUtilsはjava.util.Listタイプの値もインデックス付けされていると見なします。

PropertyUtilsのsetIndexedProperty メソッドを使用して、インデックス付きプロパティの個々の値を変更できます。

インデックス付きプロパティを変更するコードの例を次に示します。

PropertyUtils.setIndexedProperty(course, "codes[1]", "CS02");

4.3. マップされたプロパティ

基になるタイプとしてjava.util.Mapを持つプロパティは、マップされたプロパティと呼ばれます。 BeanUtilsを使用すると、String-valuedキーを使用してマップ内の個々の値を更新できます。

マップされたプロパティの値を変更するサンプルコードは次のとおりです。

Student student = new Student();
String studentName = "Joe";
student.setName(studentName);

PropertyUtils.setMappedProperty(course, "enrolledStudent(ST-1)", student);

5. ネストされたプロパティへのアクセス

プロパティ値がオブジェクトであり、そのオブジェクト内のプロパティ値にアクセスする必要がある場合、それはネストされたプロパティにアクセスします。 PropertyUtils を使用すると、ネストされたプロパティにアクセスして変更することもできます。

Courseオブジェクトを介してStudentクラスのnameプロパティにアクセスするとします。 私たちは書くかもしれません:

String name = course.getEnrolledStudent("ST-1").getName();

getNestedProperty を使用してネストされたプロパティ値にアクセスし、PropertyUtilssetNestedPropertyメソッドを使用してネストされたプロパティを変更できます。 コードは次のとおりです。

Student student = new Student();
String studentName = "Joe";
student.setName(studentName);

String nameValue 
  = (String) PropertyUtils.getNestedProperty(
  course, "enrolledStudent(ST-1).name");

6. Beanプロパティのコピー

あるオブジェクトのプロパティを別のオブジェクトにコピーすることは、開発者にとって退屈でエラーが発生しやすいことがよくあります。 BeanUtilsクラスは、ソースオブジェクトのプロパティをターゲットオブジェクトにコピーするcopyPropertiesメソッドを提供します。ここで、プロパティ名は両方のオブジェクトで同じです。

上記で作成したCourseとして、 enrolledStudent プロパティがなく、代わりにプロパティ名が student になることを除いて、同じプロパティで別のBeanクラスを作成しましょう。 そのクラスにCourseEntityという名前を付けましょう。 クラスは次のようになります。

public class CourseEntity {
    private String name;
    private List<String> codes;
    private Map<String, Student> students = new HashMap<>();

    //  standard getters/setters
}

次に、CourseオブジェクトのプロパティをCourseEntityオブジェクトにコピーします。

Course course = new Course();
course.setName("Computer Science");
course.setCodes(Arrays.asList("CS"));
course.setEnrolledStudent("ST-1", new Student());

CourseEntity courseEntity = new CourseEntity();
BeanUtils.copyProperties(courseEntity, course);

これにより、同じ名前のプロパティのみがコピーされることに注意してください。 したがって、 CourseEntity クラスには同じ名前のプロパティがないため、CourseクラスのプロパティenrolledStudentはコピーされません。

7. 結論

この簡単な記事では、BeanUtilsによって提供されるユーティリティクラスについて説明しました。 また、さまざまなタイプのプロパティと、それらの値にアクセスして変更する方法についても調べました。

最後に、ネストされたプロパティ値にアクセスし、あるオブジェクトのプロパティを別のオブジェクトにコピーすることを検討しました。

もちろん、Java SDKのリフレクションおよびイントロスペクション機能を使用すると、プロパティに動的にアクセスすることもできますが、習得が難しく、ボイラープレートコードが必要になる場合があります。 BeanUtils を使用すると、1回のメソッド呼び出しでこれらの値にアクセスして変更できます。

コードスニペットは、GitHubにあります。