如何知道实例的所有成员变量都没有设置?

时间:2011-07-21 03:26:13

标签: java accessor

假设我在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");

我需要知道person实例没有设置任何变量。但是person1至少设置了一个变量。

我能解决的问题是

  1. 创建在每个set方法中更改为true的布尔标志,或
  2. 创建一个逐个检查变量的方法。
  3. 但是我想知道是否有更优雅的方法来做到这一点。

2 个答案:

答案 0 :(得分: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;
    }


}

答案 1 :(得分:0)

我想说我们应该在Person类上有一个状态检查方法,应该在使用Person实例之前调用它(作为从数据库中过滤数据的机制)。实际上,设置一个单独的类来处理它(不是使用人)可能是一个好主意,它也可以用于其他实体。然后,这个类可以进化(可以扩展)来处理检查我们是否需要不同实体的不同逻辑。