2011-07-21 4 views
0

のは、私は1つ?インスタンスのメンバ変数がすべて設定されていないことを知るには?

によって変数1のすべてをチェックせずに(この例では、少なくとも設定されているメンバ変数のいずれかを持っているかどうかを知る方法

public class Person 
{ 
private String name; 
private int age; 
// lot of other member variables 
// get set here 
} 

クラスPersonのJavaでインスタンスを作成したとしましょうたとえば

Person person = new Person(); 
Person person1 = new Person(); 
person1.setName("John"); 

は、私はすべての変数を設定していないその人のインスタンスを知っておく必要がありますしかしPERSON1が設定した少なくとも一つの可変

。私はこれを解決するために考えることができる何

  1. にすべてのsetメソッドでtrueに変更、または
  2. が一つの変数を1つずつチェックするメソッドを作成しているブールフラグを作成することです。

しかし、もっとエレガントにこれを行うにはいくつかの方法があります場合、私は疑問に思います。

+0

名前はありません、年齢、または年齢が、名前を持た「人」エンティティーの作成を可能にすることも意味がありますか?ここでの設計は深く欠陥があるが、それはあなたがデザインの助けを探している場合は明らかではないですか、これは単にフィールドへの割り当てに関するご質問以上の機械的にサービスを提供するための一例である場合。 – seh

+0

我々は(、名= 'トムとの選択は、単に名前だけでトムとなどで人を選ぶだろうただ人との選択はDBからすべてを選択します)基準の選択の目的のためにそれを使用します。しかし、ここでは、モジュールがパフォーマンスの問題を引き起こす可能性のあるPersonの空のインスタンスを盲目的に渡していないことを確認したいだけです。 – Rudy

+0

intをクラスに追加し、各setter呼び出しでインクリメントします。多くのコアJavaクラスでは、このアプローチを使用してデータの変更を追跡します。たとえば、Calendarやその他のListの実装です。 nb:40億回の更新で、カウンタがオーバーフローして繰り返します。 –

答えて

0

これは、これは(それがjavabeanスタイルの変数のためによくチェックしないため、生産にはお勧めしません)終らする一つの方法です。あなただけ

を呼び出す必要があります。これにより

は、パラメータとしてオブジェクトを

をHelper.hasSomethingBeenSetted。

package com.intellij.generatetestcases.javadoc; 

import java.lang.*; 
import java.lang.reflect.*; 
import java.util.*; 
import java.util.regex.*; 

import static com.intellij.generatetestcases.javadoc.Person.Helper.hasSomethingBeenSetted; 

public class Person { 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 

    private String name; 
    private int age; 

    // lot of other member variables 
    // get set here 
    public static void main(java.lang.String[] args) throws InvocationTargetException, IllegalAccessException { 

     Person person = new Person(); 
     System.out.println("has been set something: " + hasSomethingBeenSetted(person)); 

     Person person1 = new Person(); 
     person1.setAge(3); 
     System.out.println("has been set something: " + hasSomethingBeenSetted(person1)); 


     Person person2 = new Person(); 
     person2.setName("john"); 
     System.out.println("has been set something: " + hasSomethingBeenSetted(person2)); 

    } 

    public static class Helper { 

     public static boolean hasSomethingBeenSetted(Person person) throws IllegalAccessException, InvocationTargetException { 
      // TODO get all javabean style attributes 

      // TODO flag to indicate something has been set, false by default 
      boolean somethingSetted = false; 

      Class<? extends Person> aClass = person.getClass(); 
      Method[] methods = aClass.getMethods(); 
      for (Method method : methods) { 
       if (method.getDeclaringClass().equals(aClass) && method.getModifiers() == Modifier.PUBLIC) { 
        Matcher matcher = Pattern.compile("get(\\p{Lu}[a-zA-Z]*)").matcher(method.getName()); 
        if (matcher.find()) { 
         // assuming there is a getter FIXME check manually this 
         Object value = method.invoke(person); 
         if (value != null) { 
          Class<? extends Object> clazz = value.getClass(); 
          if (isWrapperType(clazz)) { 
           if (clazz.equals(Boolean.class)) { 
            if (DEFAULT_BOOLEAN != (Boolean) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Byte.class)) { 
            if (DEFAULT_BYTE != (Byte) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Short.class)) { 
            if (DEFAULT_SHORT != (Short) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Integer.class)) { 
            if (DEFAULT_INT != (Integer) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Long.class)) { 
            if (DEFAULT_LONG != (Long) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Float.class)) { 
            if (DEFAULT_FLOAT != (Float) value) { 
             somethingSetted = true; 
            } 
           } else if (clazz.equals(Double.class)) { 
            if (DEFAULT_DOUBLE != (Double) value) { 
             somethingSetted = true; 
            } 
           } 
          } else { 
           somethingSetted = true; 
          } 
         } 

        } 
       } 
      } 
      return somethingSetted; 
     } 

     private static final HashSet<Class<?>> WRAPPER_TYPES = getWrapperTypes(); 


     public static boolean isWrapperType(Class<?> clazz) { 
      return WRAPPER_TYPES.contains(clazz); 
     } 

     private static HashSet<Class<?>> getWrapperTypes() { 
      HashSet<Class<?>> ret = new HashSet<Class<?>>(); 
      ret.add(Boolean.class); 
      ret.add(Character.class); 
      ret.add(Byte.class); 
      ret.add(Short.class); 
      ret.add(Integer.class); 
      ret.add(Long.class); 
      ret.add(Float.class); 
      ret.add(Double.class); 
      ret.add(Void.class); 
      return ret; 
     } 

     private static boolean DEFAULT_BOOLEAN; 
     private static byte DEFAULT_BYTE; 
     private static short DEFAULT_SHORT; 
     private static int DEFAULT_INT; 
     private static long DEFAULT_LONG; 
     private static float DEFAULT_FLOAT; 
     private static double DEFAULT_DOUBLE; 
    } 


} 
0

私はPersonクラス(データベースからデータをフィルタリングするメカニズムとして)を使用する直前に呼び出されるPersonクラスの状態チェックメソッドが必要です。では、実際にあまりにも他のエンティティのために使用することができ、これを処理するために、別のクラスを(人は使用しない)、設定するのは良い考えかもしれません。このクラスは、エンティティごとに異なるロジックが必要な場合に、チェックを処理するために展開できます(拡張可能)。

関連する問題