复制子项中的构造函数,但不复制父项

时间:2010-06-22 17:02:16

标签: java

我有以下两个类:

public class User {
     public Integer userId;
     // ...another 50-60 fields
}

public class SuperUser extends User {
}

我想在SuperUser中有一个构造函数,它接受User类型的对象并创建一个SuperUser类型的对象。例如:

public SuperUser(User theUser) {
    // not legal -> but I am looking for a one-liner to initialize this with values from theUser
    this = theUser;
}

如果User对象缺少构造函数User(User existingUser),是否有任何自动方法使用现有用户对象中的所有字段初始化SuperUser对象?我试图避免50行:

public SuperUser(User theUser) {
    this.firstName = theUser.getFirstName();
    this.lastName = theUser.getLastName();
    // and so on....
}

如果无法做到这一点,是否有像“Create Copy Constructor?”这样的重构?

谢谢!

6 个答案:

答案 0 :(得分:9)

查看commons-beanutilsBeanUtils.copyProperties(..)

SuperUser superUser = new SuperUser();
BeanUtils.copyProperties(superUser, originalUser);

或者你可以把它放在copy-constructor中:

public SuperUser(User originalUser) {
   BeanUtils.copyProperties(this, originalUser);
}

答案 1 :(得分:4)

虽然您可以使用像BeanUtils这样的东西来做您想要做的事情,但如果您需要将用户提升为超级用户或将超级用户降级为用户,您使用的是正确的抽象。

您是否可以重构代码以便用户拥有权限或权限?通常,当我觉得我需要将对象更改为层次结构中的其他对象时,我会重新排列层次结构。

例如:

public class User {
   public Integer userId;
   // ...another 50-60 fields
   public Role role;
}

public interface Role {
}
public SuperUserRole implements Role {
}

如果你不想做这个改变,那么Bozho的答案就行了。

答案 2 :(得分:1)

反思& BeanUtils很方便,但很慢。在你的情况下可能值得权衡,但我会避免它们。此外,Object.clone()不会给你你想要的东西..因为用户的clone()方法(如果实现..而且它可能不是)..将给你一个用户..而不是超级用户。

很少使用

clone()。复制构造函数或工厂方法都是合理的模式。

编辑:忘了回答这个问题。是的,手动实现复制构造函数。 Java ==很多打字。

答案 3 :(得分:0)

java.beans包可以处理这些内容:

User u = ...;
SuperUser su = ...;
BeanInfo bi = Introspector.getBeanInfo(User.class);
for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
    Method getter = bi.getReadMethod(), setter = bi.getWriteMethod();
    if (getter == null || setter == null) continue;
    setter.invoke(su, getter.invoke(u));
}

答案 4 :(得分:0)

// ...another 50-60 fields.
用户应该拥有String firstName这样的字段,而不是Name name等,其中包含头,尾,标题等。

您可以为您的地址,联系方式等执行相同的操作。这会使复制构造函数变得更加容易。

BTW,因为SuperUser扩展了User,你的构造函数将是

public SuperUser(User user){
    super(user); //the User constructor would do the copy
    //initialize other  fields...
}

答案 5 :(得分:0)

如果您想在Android上使用BeanUtils但没有运气,请尝试使用android-java-air-bridge。 https://code.google.com/p/android-java-air-bridge/

只需下载android-java-air-bridge.jar.zip,解压缩.jar并导入到您的项目中,无需更改任何代码。

示例:

import javadz.beanutils.BeanUtils;

BeanUtils.copyProperties(superUser, originalUser);