在构造函数中逐字段复制-我需要更简洁的形式

时间:2019-04-24 09:14:54

标签: java constructor instance

我正在尝试编写一个构造函数,该构造函数根据超类的现有实例创建一个类的实例;我知道聚合-本来可以创建MyClass类型的字段-但我不想使用它。所以我要做的是依次将每个字段初始化,如下所示:

public MyClassExtension extends MyClass
{
    Object new_field;

    public MyClassExtension(MyClass instance) 
    {
        this.field_1 = instance.field_1;
        this.field_2 = instance.field_2;

            ......
        this.field_20= instance.field_20;

        this.new_field= some_value;
    }
}

问题在于这种方法非常冗长。 是否可以用较短的形式获得相同的结果?

尝试

  • 调用super(instance)会给出'构造函数未定义'错误;确实,没有这样的构造函数; 即使我创建了它,同样的问题也适用于该构造函数

  • 调用this(instance)会给出“递归构造函数调用” 错误,这很正常,因为我正在调用 自身的方法,没有停止条件

上下文信息::MyClass是javax.persistence.Entity,因此字段数量很多。 MyClassExtension添加了一些布尔值,这些布尔值存储UI元素的可见性,具体取决于数据。

注意:技术堆栈限制了我使用这种方法。在EL 2.2之前,我无法称呼 JSF的backend方法,以确定UI元素的可见性。 参见:How to call a method with a parameter in JSF

编辑:我已阅读Copy constructor using reflection,但没有答案适用于我:

  • 第一个答案:未经经理的批准,我无法在现有项目中引入外部库;我需要核心Java 功能

  • 第二个答案:我已经尝试过super()-见上文-我不会重复我的解释

1 个答案:

答案 0 :(得分:-2)

您可以执行以下操作:

public MyClassExtension(MyClass instance) {
    super(...);
    new_field = some_value;
}

在创建子类时,最好调用超级构造函数(否则默认情况下将调用默认的超级构造函数)。

为什么?,因为它限制了您需要重新定义相同初始化的次数。例如,当您要使用默认值创建对象时。您只需在母类中执行一次,并且在创建子类时默认调用默认的超级构造函数。您还可以根据定义类的方式来覆盖子类中的默认值。

这里是一个示例:假设您定义了MyClass,如下所示:

class MyClass {
    protected Object field1;
    protected Object field2;
    protected Object field3;

    public MyClass(MyClass c) {
        field1 = c.field1; // Remark: this is only the setup of
        field2 = c.field2; // the reference. If you want to create a
        field3 = c.field3; // copy, please do so with a constructor.
    }

    public MyClass(Object field1, Object field2, object field3) {
        this.field1 = field1; // Same remark here
        this.field2 = field2; // (about references).
        this.field3 = field3;
    }
}

您在这里看到MyClass定义了2个构造函数:一个以MyClass对象作为参数的所谓复制构造函数,以及一个具有所有必需字段的构造函数。

然后,当您要创建一个以MyClass对象作为参数的子类时,可以执行以下操作:

class MyClassExtension extends MyClass {
    private Object newField;

    public MyClassExtension(MyClass c, Object newField) {
        super(c);
        this.newField = newField;
    }
}

但是您也可以这样做:

class MyClassExtension {
    private Object newField;

    public MyClassExtension(MyClass c, Object newField) {
        super(c.field1, c.field2, c.field3);
        this.newField = newField;
    }
}

因此,您可以限制对MyClass对象参数的访问次数,并且子类MyClassExtension的构造方法很简洁。

注意,您确实必须在程序中的某个位置或其他位置提供此代码。给定MyClassExtension对象,您必须为编译器定义如何构建MyClass。代码在MyClass中,或者在MyClassMyClassExtension中。如果您要更改代码中的任何内容,我仅提供一种减少代码库并限制所需更改次数的方法。使用此解决方案,如果更改MyClass构造函数,MyClassExtension也将受到影响(除非您强制执行其他操作)。

还要注意,您需要自己定义副本构造函数,因为否则编译器将不知道您要 deep 复制还是仅 reference < / em>复制。更多信息,请点击http://blog.amitinside.com/Copy-Constructor-in-Java/