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

Java 在构造函数中逐字段复制-我需要更简洁的形式,java,constructor,instance,Java,Constructor,Instance,我试图编写一个构造函数,它从一个已经存在的超类实例创建一个类实例;我知道聚合——我本可以创建MyClass类型的字段——但我不想使用它。所以我要做的是依次对每个字段进行初始化,如下所示: public MyClassExtension extends MyClass { Object new_field; public MyClassExtension(MyClass instance) { this.field_1 = instance.field_

我试图编写一个构造函数,它从一个已经存在的超类实例创建一个类实例;我知道聚合——我本可以创建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元素的可见性。 见:

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

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

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


    • 您可以做的是:

      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
      定义了两个构造函数:一个所谓的复制构造函数,将
      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
      构造函数非常简洁

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


      还要注意您需要自己定义复制构造函数,否则编译器就不知道您是要深度复制还是只引用复制。此处的更多信息

      “默认情况下,在创建子类时,您需要调用超级构造函数。”如果没有参数的构造函数(默认构造函数也可以使用)可用,则不需要调用超级构造函数,如果您不这样做,它将自动调用。是的,非常抱歉这个不精确。但是您知道问题是关于必须复制20+变量的冗长性吗?OPs不想关联
      MyClassExtension
      MyClass
      ,请解释继承。默认情况下,由于编译器操作,调用
      super()
      构造函数将已经发生。现在还不清楚你在这里为你的答案声称了什么,或者你认为
      super()
      构造函数有什么神奇的特性,或者它是如何回答被问到的问题的。@belka:请用具体的东西替换这些点,这样我就可以知道您的解决方案是否有效,或者apache beanutils解决方案的可能副本是否符合您的需要。我从未尝试过,但这应该正是您想要的。只有当您有几十个或数百个实例字段时,它才是详细的,而这些字段已经很详细了。22年来,我从未用Java使用或编写过所谓的“复制构造函数”。为什么您认为您需要一个呢?@user207421:javax实体列表被迭代并显示在一个表中。某些UI根据数据显示。因此,我正在包装实体,并包含与UI元素可见性相关的布尔值。我之所以选择这种方法是因为技术堆栈的局限性——请阅读我在问题“上下文信息”部分的解释好吧,让我们承认20行并不冗长,尽管我有更多字段的实体。但是当复制粘贴时,总是有可能丢失一些字段,这些字段将有一个默认值,并以这种方式引入微妙的错误。实际上,这不是手工复制20个字段的工作。