2011-07-21 54 views
0

比方說,我在Java中創建了一個Person類如何知道一個實例的所有成員變量都沒有設置?

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

如何知道的實例此實例是否至少有被設置成員變量的一個(沒有一個?

檢查所有的變量之一

例如:

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

我需要知道那個人實例尚未設置任何變量但是PERSON1已至少設置一個變量

我能想到的解決這是

  1. 創建被更改爲true,每一套方法,或
  2. 創建檢查一個變量一個方法布爾標誌。

但我不知道是否有更優雅的方法來做到這一點。

+0

允許創建一個有名字但沒有年齡或年齡但沒有名字的「人」實體是否有意義?這裏的設計有很大的缺陷,但是不清楚你是否在尋求設計方面的幫助,或者這只是一個例子,可以用來解釋關於分配到領域的更多機械問題。 – seh

+0

我們將它用於標準選擇目的(只選擇Person將選擇所有的數據庫,選擇名稱='Tom'將只選擇名稱爲tom的人等)。但在這裏,我只想確保模塊不會盲目傳遞可能導致性能問題的Person的空實例。 – Rudy

+0

向您的類中添加一個int,並在每個setter調用中增加它。很多核心Java類使用這種方法來跟蹤數據的變化 - 例如Calendar和misc 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實例(作爲一種機制,從數據庫中篩選數據)的狀態檢查方法。事實上,建立一個單獨的類來處理這個問題(不是使用人)可能是一個好主意,它也可以用於其他實體。然後這個類可以進化(可以擴展)來處理檢查是否需要不同實體的不同邏輯。

相關問題