→[[Java関連]]

#contents



*ほぼ同じメンバを持っているが継承関係はないクラス c -> d への値コピー [#tdab8758]
 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);
 }


*リフレクションを使った汎用ディープコピー [#cb55d43b]
 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;
 }


*リフレクションを使った汎用のクラス比較 [#l550a89b]
 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