Java関連

ほぼ同じメンバを持っているが継承関係はないクラス c -> d への値コピー

Class c_cls = c.getClass();
Class d_cls = d.getClass();
Field[] d_flds = d_cls.getDeclaredFields();
for (Field f: d_flds) {
    f.setAccessible(true);
    Field c_fld = c_cls.getField(f.getName());
    c_fld.setAccessible(true);
    Object val = c_fld.get(c);
    f.set(d, val);
}

リフレクションを使った汎用ディープコピー

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public static Object DeepCopy(Object obj) {
   // 対象オブジェクトのクラスを取得
   Class cls = obj.getClass();

   Object clone = cls.newInstance();
 
   // クラスに宣言されたすべてのフィールドを設定
   Field[] fields = cls.getDeclaredFields();
   for (int i = 0; i < fields.length; i++) {
     Field field = fields[i];
     field.setAccessible(true);
     // アクセス制御属性がfinalでなければ値set
     if ( ! Modifier.isFinal(field.getModifiers())) {
       field.set(clone, field.get(obj));
     }
   }
   
   // 渡されたオブジェクトの親クラスをさかのぼる
   while( true ) {
     cls = cls.getSuperclass();
     // Objectクラスまで到達したら終了
     if ( Object.class.equals(cls)) break;
     Field[] sFields = cls.getDeclaredFields();
     for (int i = 0; i < sFields.length; i++) {
       Field field = sFields[i];
       // アクセス制御属性がfinalでなければ値をset
       if ( ! Modifier.isFinal(field.getModifiers())) {
         field.setAccessible(true);
         field.set(clone, field.get(obj));
       }
     }
   }
   return clone;
}

リフレクションを使った汎用のクラス比較

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public final class EntityCompareUtil {
  @SuppressWarnings("unchecked")
	public static boolean compare(Object obj1, Object obj2) 
          throws IllegalArgumentException, IllegalAccessException{

    // どちらもnullなら一致。
  	if((obj1 == null) && (obj2 == null)){
         return true;
       }
    // どちらかがnullなら不一致。
  	if((obj1 == null) || (obj2 == null)){
          return false;
       }
     // 渡されたオブジェクトのクラスを取得
  	Class targetClass = obj1.getClass();
    
    // クラスの一致チェック
  	if(!targetClass.equals(obj2.getClass())){
      // クラスが違うので不一致
    	return false;
    }

    // Object型まで親クラスを辿る。
  	for(;!Object.class.equals(targetClass);targetClass = targetClass.getSuperclass()){
      
    	Field[] fields = targetClass.getDeclaredFields();
  
      // フィールドの数だけ繰り返す。
    	for(int i=0; i<fields.length; i++){
        // リフレクションを利用してプロパティに直接アクセスする
      	fields[i].setAccessible(true);

        // final属性のフィールドはスキップ
      	if ( Modifier.isFinal(fields[i].getModifiers())){continue;}

        // 値取得
      	Object field1 = fields[i].get(obj1);
      	Object field2 = fields[i].get(obj2);

      	if((field1 == null) && (field2 == null)){continue;}

        // 一箇所でも違えばfalse
      	if((field1 == null) || (field2 == null)){return false;}
      	if(!field1.equals(field2)){return false;}

      }
    }
  	return true;
  }

}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS