How to know that all of the member variables of an instance have not been set?
Let's say I created an instance in Java of a class Person
public class Person
{
private String name;
private int age;
// lot of other member variables
// get set here
}
How to know whether this instance at least have one of member variables being set (without checking all of the variables one by one?
For example :
Person pers开发者_StackOverflowon = new Person();
Person person1 = new Person();
person1.setName("John");
I need to know that person instance has not set any variables. However person1 has set at least one variable.
What I can think for solving this is to
- create boolean flag that being changed to true in every set method, or
- create a method that checking the variables one by one.
But I wonder if there's some way that more elegant to do this.
This is one way to get this done (not recommended for production because it doesn't check well for javabean style variables).
With this you only have to call
Helper.hasSomethingBeenSetted
with the object as parameter.
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;
}
}
I would say we should have a state checking method on the Person class which should be called just before you use the Person instance (as a mechanism to filter data from database). In-fact it might be a good idea to set up a separate class to handle this(not use person), which can be used for other entities too. This class can then evolve (can be extended) to handle checking if we need different logic for different entities.
精彩评论