在将一个对象复制到另一个对象时,如何避免如此多的 if 语句?



我有以下类:

public class File
{
@Getter
@Setter
private String id;
@Getter
@Setter
private String name;
@Getter 
@Setter
private int size;
@Getter
@Setter
private String color;
... about 10 more variables
}

我有两个此类实例:

File file = new File(); // assume each variable has a value initialized
File newFile = new File(); // assume each variable has a value initialized

我想要的逻辑是,如果我的newFile包含变量的值,我想保留它。否则,我想回退到file对象中的原始值。

所以我有以下方法:

public void merge(File oldFile, File newFile)
{
if (newFile.getId() != null)
{
oldFile.setId(newFile.getId());
}
if (newFile.getName() != null)
{
oldFile.setName(newFile.getName());
}
if (newFile.getSize() != null)
{
oldFile.setSize(newFile.getSize());
}
if (newFile.getColor() != null)
{
oldFile.setColor(newFile.getColor());
}
... etc
}

如何避免如此多的 if 语句和空检查?在我看来,代码看起来很丑陋。

如果新值为 null,您可以编写一个默认为旧值的函数 - 或者您可以使用预先编写的函数,例如: https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/ObjectUtils.html#defaultIfNull(T,%20T(

这意味着您的代码变为:

public void merge(File oldFile, File newFile)
{
oldFile.setId(defaultIfNull(newFile.getId(), oldFile.getId());
oldFile.setName(defaultIfNull(newFile.getName(), oldFile.getName());
oldFile.setSize(defaultIfNull(newFile.getSize(), oldFile.getSize());
// etc

}

当然,如果您决定此行为应始终适用于您的文件,那么您可以将其放入所有 setter 中,例如:

public void setName(String name) {
this.name = defaultIfNull(name, this.name);
}

然后像往常一样打电话:

public void merge(File oldFile, File newFile)
{
oldFile.setId(newFile.getId());
oldFile.setName(newFile.getName());
// etc
}

您可以在 Utility 类中创建merge函数,该函数接受两个文件对象并使用反射来执行此操作

static final class FileUtil {
private FileUtil() throws IllegalAccessException {
throw new IllegalAccessException("can not create an object from this class!");
}
public final static void merge(File oldFile, File newFile) throws Exception {
Method[] methods = newFile.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().contains("get")) {
Object value = m.invoke(newFile);
if (value != null) {
String name = m.getName();
name = name.substring(name.indexOf("get") + 3);
name = "set" + name;
if (value instanceof Integer) {
Method method = oldFile.getClass().getDeclaredMethod(name, int.class);
method.invoke(oldFile, (int) value);
} else {
Method method = oldFile.getClass().getDeclaredMethod(name, value.getClass());
method.invoke(oldFile, value);
}
}
}
}
}
}

最新更新