web-dev-qa-db-ja.com

HashMapからオブジェクトフィールドを設定する

次のことができるライブラリはありますか?:

オブジェクトとHashMapを指定すると、ハッシュマップのキーを列挙し、オブジェクト内のこれらのキーのセッターを検索して、関連する値を設定します。そのように見えるもの:

public Object setData(Object object, HashMap<String, Object> fields) {
   for (Entry<String, Object> entry : fields.entrySet()) {
      Method m = object.getClass().getMethod("set" + entry.getKey(), entry.getValue().getClass());
      if (m != null) {
         m.invoke(object, entry.getValue());
      }
   }
   return object;
}

タスクは一見シンプルに見えますが、誰かがすでに世話をしてくれることを願っているニュアンスがいくつかあります。ご存知のように、車輪の再発明(良い車輪)は悪いアプローチです。

20
forker

Apache CommonsBeanUtilsを見てください

org.Apache.commons.beanutils.BeanUtils.populate(Object bean, Map properties)

Javadoc:
指定された名前と値のペアに基づいて、指定されたBeanのJavaBeansプロパティにデータを入力します。このメソッドは、JavaリフレクションAPIを使用して、対応する「プロパティセッター」メソッド名を識別し、String、boolean、int、long、float、およびdouble型のセッター引数を処理します。

20
e-zinc

より良い使用 BeanUtils クラス:

public Object setData(Object object, HashMap<String, Object> fields) {
   for(Entry<String, Object> entry : fields.entrySet()) {
      BeanUtils.setProperty(object, entry.getKey(), entry.getValue());
   }
   return object;
}
7

私はずっと前に書いた BeanAsMap クラスを持っています。メソッドasMapは、Java Bean(POJO)のビューであるMapを返します。そのputAllMapを呼び出し、データのコピー元のMapを渡すことができます。

上記の私のコードを自由に使用してください。

例:

MyClass bean = ...;
Map<String, Object> inputData = ...;

Map<String, Object> view = BeanAsMap.asMap(bean);
view.putAll(inputData);
3
Jesper

BeanUtilsは問題ありません。

ただし、グッドプラクティスとして、リフレクションを使用するコードは記述しません。または、他に何も見つからなかった場合、私が持っている最後の解決策として。

このコードは、Eclipse(呼び出し階層なし)のようにIDEで追跡できないため、開発者はセッターが呼び出されないと思わせます。彼はコードを壊す可能性があり、それでもコンパイルされます。

このような抽象化のレベルが高すぎると、コードが理解しにくくなります。

難読化されているコードは、そのようなものを書くときに難読化ツール自体によって破壊されます。

最善の解決策は、リフレクションを使用してオブジェクトフィールドを設定することを再考することです。

2
Jerome L
0
quaylar