【问题标题】:Why do we need this special type of constructor?为什么我们需要这种特殊类型的构造函数?
【发布时间】:2015-05-23 17:09:00
【问题描述】:
public MyConstructor(MyConstructor mc){
   this.setId(mc.getId());
   this.setName(mc.getName());
}

这里为什么我们需要通过获取它的getter方法来设置构造函数中的值。这背后有什么特殊目的吗?

【问题讨论】:

  • 嗨,唯一的原因是访问器(getter/setter)是否有一些逻辑。
  • 您不使用正在创建的对象 (this) 中的 getter,而是使用正在复制的对象中的 getter (mc)
  • 如果你愿意,构造函数代码可以写成this.id = mc.id;(假设有一个名为id的支持字段)。或setId(mc.id)。或setId(mc.getId()).
  • 在这种情况下,this 是可选的,但如果你有public Constructor(int x){ this.x = x; },那么你需要this 来确定哪个x 是字段,哪个是构造函数的参数。
  • 添加到 Vyncent 的评论中:...或者他们是否可能在未来获得一些逻辑(概率取决于您期望如何开发/使用该类)。如果您直接使用this.id = mc.id 形式,当您决定 setter 或 getter 需要一些额外的逻辑时,您还必须更改构造函数。

标签: java constructor domain-object


【解决方案1】:

正如其他答案中已经指出的那样,这种构造函数主要用于克隆对象,有时称为复制构造函数

正如 Joshua Bloch 在他的书“Effective Java”第 11 项中所建议的那样,这种构造函数通常比实现 clone() 方法更可取,因为 clone() 方法存在一些问题(有关详细信息,请参阅本书或相应的 stackoverflow 问题)。

没有明显的理由完全像那样实现它 - 因此,人们并不真正需要完全这种形式。如 cmets 中所述,可以(很可能)将其写为

public MyConstructor(MyConstructor mc){
    this.id = mc.getId();
    this.name = mc.getName();
}

public MyConstructor(MyConstructor mc){
    this.setId(mc.id);
    this.setName(mc.name);
}

public MyConstructor(MyConstructor mc){
    this.id = mc.id;
    this.name = mc.name;
}

这里笔者选择使用嵌套set(mc.get())的方式。它具有潜在的优势,即它仅依赖于根据get/set 方法定义的接口,因此可能对更改更加健壮。

一般来说,人们可能会争论这是否是一种好的做法,但我认为对于复制构造函数,它很好且清楚地指出:“这个对象在这里初始化,完全基于(并且完全像)给定的对象” .


附注:克隆一个对象并为克隆提供相同的 ID 很可能会破坏 ID 的目的 - 但在某些情况下这样做可能是合适的

【讨论】:

    【解决方案2】:

    暂时考虑克隆对象,但这不是克隆。如果您遇到手上有一个MyConstructor(type) 对象的情况,您需要创建另一个具有相同对象类型MyConstructornew 对象。所以,在你的MyConstructor 类中,你需要一个像上面这样的构造函数。

    在那里,您将手中的对象拿走并获取该对象的 id当您创建全新的第二个对象时

    【讨论】:

      【解决方案3】:

      这样的构造函数背后的目的主要是为了克隆。 假设您需要将一个对象的值分配给另一个对象而不是引用,这将正常工作。

      这里已经讨论过了: How do I copy an object in Java?

      【讨论】:

        【解决方案4】:

        如果您的类将由(子)类派生,则这一点很重要。

        public class Child extends Parent {
        
            private int id;
            private String name = "Child";
        
            ...
            // getter and setters...
        }
        
        
        public class Parent {
        
            private int id;
            private String name = "Parent";
        
            public Parent(Parent parent) {
                this.setId(parent.getId());
                // option#1
                this.setName(parent.getName());
                // option#2
                // this.name = parent.name;
            }
            ...
            // getter and setters...
        }
        

        示例主要:

        public class Main {
            public static void main(String ...strings ) {
        
                Parent parent = new Parent();
                Child child = new Child();
        
                Parent parent2 = new Parent(child);
                System.out.println(parent2.getName());
        
            }
        }
        

        输出:

        Child
        

        但如果我们使用 Option#2 this.name = parent.name 而不是输出将是

        Parent
        

        【讨论】:

          猜你喜欢
          • 2011-02-04
          • 1970-01-01
          • 2018-08-22
          • 2011-04-14
          • 2023-04-09
          • 2015-02-24
          • 2021-10-15
          • 2014-05-27
          • 2023-03-13
          相关资源
          最近更新 更多