2011-07-21 34 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实例(作为一种机制,从数据库中筛选数据)的状态检查方法。事实上,建立一个单独的类来处理这个问题(不是使用人)可能是一个好主意,它也可以用于其他实体。然后这个类可以进化(可以扩展)来处理检查是否需要不同实体的不同逻辑。

相关问题