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

问题描述 投票:0回答:1

我试图编写一个构造函数,从一个已经存在的超类实例创建一个类的实例;我知道聚合 - 我可以创建一个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调用后端方法来确定UI元素的可见性。见:How to call a method with a parameter in JSF

编辑:我读过Copy constructor using reflection,但没有一个答案适用于我:

  • 第一个答案:未经我的经理批准,我不能在现有项目中引入外部库;我需要核心Java功能
  • 第二个答案:我已经尝试过super() - 见上文 - 我不会重复我的解释
java constructor instance
1个回答
-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也将受到影响(除非您强制执行其他操作)。

另请注意,您需要自己定义复制构造函数,否则编译器将无法知道您是要进行深层复制还是仅仅引用复制。更多信息,请访问http://blog.amitinside.com/Copy-Constructor-in-Java/

© www.soinside.com 2019 - 2024. All rights reserved.