Java関連

関連記事

引数にクラスを渡してその継承クラスがあれば継承クラスでインスタンスを作る

  • 基本クラスを B_xxx クラス、派生クラスを C_xxx クラスというネーミングルールで作っておき、以下のようなメソッドで生成する。とか
protected static final Object createInstance(Class<?> myClass){

  Object instance = null;
  // JVM上に継承クラスがある場合は、継承クラスでインスタンス作成
  try{
      Class<?> cls = Class.forName("jp.co.xxx.hogehoge." + myClass.getSimpleName().replace("B_", "C_"));
      instance = ConstructorUtils.invokeConstructor(cls, null);
  }
  catch (Exception e){
      LogWriter.putLog(myClass.getName(), LogWriter.INFO, myClass.getSimpleName() + "の継承クラスなし");
  }

  // JVM上に継承クラスがない場合は、そのままインスタンス作成
  if(instance == null){
      try {
          instance = ConstructorUtils.invokeConstructor(myClass, null);
      }
      catch (Exception e){
          LogWriter.putError(myClass.getName(), LogWriter.FATAL, "インスタンス生成失敗", e);
          throw new HogeException();
      }
  }
  return instance;
}

Enumの列挙

enum HogeEnum {
   Foo, Bar
}
for(HogeEnum value : HogeEnum.values()) {
    valueを使って何かする
}

ほぼ同じメンバを持っているが継承関係はないクラス 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
Last-modified: 2016-07-11 (月) 23:16:12 (1698d)