假设我在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至少设置了一个变量。
我能解决的问题是
但是我想知道是否有更优雅的方法来做到这一点。
答案 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实例之前调用它(作为从数据库中过滤数据的机制)。实际上,设置一个单独的类来处理它(不是使用人)可能是一个好主意,它也可以用于其他实体。然后,这个类可以进化(可以扩展)来处理检查我们是否需要不同实体的不同逻辑。